# Workflow Action - Custom webhook

> Learn to use GHL Customer Care’s Custom Webhook action—configure auth, headers, params, payloads—and test requests. Includes GET/POST/PUT/DELETE examples.

- Source: https://docs.ghlcustomercare.com/docs/workflows/webhooks-workflow-actions/workflow-action-custom-webhook
- Section: Workflows / Webhooks Workflow Actions
- Reading time: 7 min
- Images: 10, each explained below

---
GHL Customer Care’s **Custom Webhook** workflow action lets you send real‑time data to external services using GET, POST, PUT, and DELETE requests. Configure auth, headers, query parameters, and JSON/form payloads to connect CRMs, apps, and custom APIs—without code. This article explains setup, best practices, and working examples to help you ship reliable integrations fast.

---

**TABLE OF CONTENTS**

-   [What is Custom Webhook?](#what-is-custom-webhook)
-   [Key Benefits of Custom Webhook](#key-benefits-of-custom-webhook)
-   [Authentication Options](#authentication-options)
-   [HTTP Methods & Request Components](#http-methods-and-request-components)
-   [Event vs Method (UI Behavior)](#event-vs-method-ui-behavior)
-   [Headers & Query Parameters](#headers-and-query-parameters)
-   [Payload & Field Mapping](#payload-and-field-mapping)
-   [Testing & Troubleshooting](#testing-and-troubleshooting)
-   [How To Set Up Custom Webhook](#how-to-set-up-custom-webhook)
-   [Frequently Asked Questions](#frequently-asked-questions)

---

# **What is Custom Webhook?**

Custom Webhook is an outbound workflow action that makes an HTTP request to a URL you choose. When a workflow run reaches this step, GHL Customer Care assembles your headers, parameters, and payload (including mapped dynamic values) and sends the request to the external system.

---

## **Key Benefits of Custom Webhook**

Understanding where Custom Webhook shines helps you pick the right automation tool and structure requests correctly for your provider.

-   **Flexible methods:** Use GET, POST, PUT, DELETE to match any API operation.

-   **Authentication options:****Bearer token**, **API key**, **Basic Auth**, **OAuth2**, or **No auth** with custom headers.

-   **Precise data mapping:** **Dynamic values** (e.g., {{contact.email}}) populate headers, params, or body so every call includes the right record details.

-   **Reusable patterns:** Build once, reuse across workflows with consistent headers, content types, and payload shapes.

-   **Faster troubleshooting:** Optional response capture and workflow execution logs streamline testing and issue resolution.

---

## **Authentication Options**

External APIs often require credentials. Choose the option your provider supports and place secrets in headers—not URLs—for better security.

-   **Bearer Token**
    
    Use header Authorization: Bearer <token>.
    
    _Example header:_
    

```
Authorization: Bearer {{location.api_token}}
```

-   **API Key**
    
    Most services expect a custom header (e.g., X-API-Key: <key>). Only use query‑string keys if the provider requires it.
    
    _Header example:_
    

```
X-API-Key: {{location.external_api_key}}
```

-   _Query example (only if required):_ ?api\_key={{location.external\_api\_key}}
    
-   **Basic Auth**
    
    Provide **Username** and **Password** in the action’s Authorization fields. GHL Customer Care sends the proper Authorization: Basic ... header.
    
-   **OAuth2**
    
    If your provider uses OAuth2, first configure the token in **Global Workflow Settings → OAuth2 / Manage Tokens**, then select it in the action. OAuth2 is recommended for providers that rotate or refresh tokens automatically.
    
-   **No Auth + Custom Header**
    
    If your provider asks for a bespoke header (e.g., X-Signature: <secret>), choose **No auth**, then add the header under **Headers**.
    

---

## **HTTP Methods & Request Components**

Matching the correct method and placing data in the right part of the request prevents 400/401/422 errors and speeds up integrations.

-   **URL & Path Parameters:** You can include variables in the path, e.g., https://api.example.com/contacts/{{contact.id}}.

-   **GET:** Retrieve data. Bodies are typically ignored—use query parameters: [https://api.example.com/leads?email={{contact.email}}&status=active](https://api.example.com/leads?email={{contact.email}}&status=active)

-   **POST:** Create resources. Send a JSON body or form data (see Content‑Type).

-   **PUT:** Update resources. Usually requires an ID in the path and a JSON body.

-   **DELETE:** Remove resources. Often includes the ID in the path.

-   **Content‑Type:** Common values: application/json (JSON body) or application/x-www-form-urlencoded (form fields). Match your provider’s docs.

---

## **Event vs Method (UI Behavior)**

The Custom Webhook action offers two configuration modes. **CUSTOM** exposes full control (method, content type, raw body). **GET/POST** offer simplified experiences. Pick the mode that matches your provider’s requirements.

-   **Event = CUSTOM (advanced):**
    
    -   Shows **Method** (GET, POST, PUT, DELETE), **Content-Type**, and **Raw Body** editor for JSON or other formats.
        
    -   Best when you need JSON payloads, non‑POST methods, or explicit headers/content types.
        
-   **Event = POST (simple):**
    
    -   Shows **Body (Key and Value)** pairs for a form‑style payload; no Raw Body editor.
        
    -   Use for simple key/value submissions. Switch to **CUSTOM** if your provider expects JSON.
        
-   **Event = GET (simple):**
    
    -   No request body. Use **Query Parameters** for filters. **Save response from this Webhook** is available.
        
-   **Event picker:**
    
    -   The **Event** dropdown controls which fields appear. Choose **CUSTOM** for full control.
        
-   **Variable picker:**
    
    -   The small _tag_ icon next to fields (URL, Headers, Query Params, Body) opens the dynamic value picker to insert values like {{contact.id}}.
        

---

## **Headers & Query Parameters**

APIs commonly require specific headers and query parameters for auth, content type, versioning, or filtering. Map dynamic values when needed.

-   **Headers (examples):**
    

```
Authorization: Bearer {{location.api_token}} Content-Type: application/json X-API-Key: {{location.external_api_key}} X-App-Version: 2024-11-01
```

-   **Query parameters (examples):**
    

```
lead_id={{contact.id}} email={{contact.email}} source=workflow
```

-   Avoid putting secrets in query strings unless your provider requires it.
    

---

## **Payload & Field Mapping**

Dynamic values let you personalize each request with contact, opportunity, or other workflow data—shaped to match the external API.

-   **Flat JSON payload (POST / create):**
    

```
{  "id": "{{contact.id}}",  "first_name": "{{contact.first_name}}",  "last_name": "{{contact.last_name}}",  "email": "{{contact.email}}",  "phone": "{{contact.phone}}" }
```

-   **Nested JSON:**
    

```
{  "contact": {    "id": "{{contact.id}}",    "name": "{{contact.name}}",    "phones": ["{{contact.phone}}"],    "tags": ["{{contact.tag}}", "new-lead"]  } }
```

-   **Form‑encoded:** Set Content‑Type to application/x-www-form-urlencoded and provide key/value pairs instead of JSON.
    

---

## **Testing & Troubleshooting**

Validating requests before you go live prevents broken automations. Use both provider‑side tools and workflow logs.

-   Use **Test Workflow** (draft mode) with a sample record to trigger the action.

-   Send test calls to tools like **Webhook.site** or **Postman** collections to confirm headers, params, and payload shape.

-   Verify basics first: correct URL, method, **Content‑Type**, required headers, and valid credentials.

-   Check **Execution Logs** / run history to confirm the action fired and review status codes.

-   If you don’t see **Content‑Type** or a **Raw Body** editor, verify the **Event** selection. Choose **CUSTOM** for JSON payloads or **PUT/DELETE** requests.

-   Common HTTP responses:
    
    -   **400/422** Invalid payload → match the provider’s required fields and types.
        
    -   **401/403** Unauthorized/Forbidden → fix token, key, scope, or account permissions.
        
    -   **404** Wrong path/ID → confirm endpoint and path variables.
        
    -   **409** Conflict/idempotency → ensure unique IDs or follow provider’s upsert rules.
        
    -   **429** Rate limited → slow down or add delays/retries per provider limits.
        
    -   **5xx** Provider error → retry later and contact provider support.
        

---

## **How To Set Up Custom Webhook**

A clear, repeatable setup reduces errors and ensures your requests match the provider’s expectations. Use the steps below to configure the URL, event/method, authorization, headers/params, and payload correctly before testing.

### **Open your workflow**

Navigate to **Automation → Workflows** and open the workflow where you want to send data so the run reaches this action with the right record context.

![Open your workflow (image 1 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060390113/original/9QPiR4rF7uyh_YfNxki6M-a8FESN4-dekw.png)

**Open your workflow (image 1 of 10)**

This screenshot appears in the "Open your workflow" section of "Workflow Action - Custom webhook". The text alongside this image reads: Navigate to Automation → Workflows and open the workflow where you want to send data so the run reaches this action with the right record context. Immediately after, the guide continues: Click + Add action → Send Data → Custom Webhook to create the step that will make the outbound HTTP call. Screenshot (placeholder): Action Drawer — Add the Custom Webhook action from Send Data. Alt text: Workflow action drawer showing….
- Where to go: Navigate to Automation → Workflows and open the workflow where you want to send data so the run reaches this action with the right record context.
- Controls: Automation → Workflows
- Next: Click + Add action → Send Data → Custom Webhook to create the step that will make the outbound HTTP call. Screenshot (placeholder): Action Drawer — Add the Custom Webhook action from Send Data. Alt text: Workflow action drawer showing Webhook and Custom Webhook.

### **Add the action**

Click **\+ Add action → Send Data → Custom Webhook** to create the step that will make the outbound HTTP call. Screenshot (placeholder): Action Drawer — Add the Custom Webhook action from Send Data. Alt text: Workflow action drawer showing Webhook and Custom Webhook.

![Add the action (image 2 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060390153/original/ZfDK-0LbEyoBv-aDfjdBYq1kqyPxyV526Q.png)

**Add the action (image 2 of 10)**

This screenshot appears in the "Add the action" section of "Workflow Action - Custom webhook". The text alongside this image reads: Click + Add action → Send Data → Custom Webhook to create the step that will make the outbound HTTP call. Screenshot (placeholder): Action Drawer — Add the Custom Webhook action from Send Data. Alt text: Workflow action drawer showing Webhook and Custom Webhook. Immediately after, the guide continues: Give the action a clear, descriptive name to simplify reading and troubleshooting later; for example, Send Lead to External CRM.
- What to click: Click + Add action → Send Data → Custom Webhook to create the step that will make the outbound HTTP call. Screenshot (placeholder): Action Drawer — Add the Custom Webhook action from Send Data. Alt text: Workflow action drawer showing Webhook and Custom Webhook.
- Next: Give the action a clear, descriptive name to simplify reading and troubleshooting later; for example, Send Lead to External CRM.

### **Name the action**

Give the action a clear, descriptive name to simplify reading and troubleshooting later; for example, **Send Lead to External CRM**.

![Name the action (image 3 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060390603/original/m62IhxkcMDBAgaYHRb1wS2nhIMO1Sm2R5A.png)

**Name the action (image 3 of 10)**

This screenshot appears in the "Name the action" section of "Workflow Action - Custom webhook". The text alongside this image reads: Give the action a clear, descriptive name to simplify reading and troubleshooting later; for example, Send Lead to External CRM. Immediately after, the guide continues: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw….
- What this covers: Give the action a clear, descriptive name to simplify reading and troubleshooting later; for example, Send Lead to External CRM.
- Controls: Send Lead to External CRM
- Next: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw body editor. GET has no body; use Query Parameters to pass filters. The small tag icon next to fields opens the dynamic value picker (for example, {{contact.id}}).

### **Select the Event (and Method when applicable)**

Choose the **Event** that matches your use case. **CUSTOM** reveals the **Method** picker (GET, POST, PUT, DELETE), **Content-Type**, and a **Raw Body** editor for JSON or other formats. **POST** provides a simple **Body (Key and Value)** interface without a raw body editor. **GET** has no body; use **Query Parameters** to pass filters. The small tag icon next to fields opens the dynamic value picker (for example, {{contact.id}}).

![Select the Event (and Method when applicable) (image 4 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060390671/original/v0KY7TzROj4I2rS8jMFuibS7UK835pXlhg.png)

**Select the Event (and Method when applicable) (image 4 of 10)**

This screenshot appears in the "Select the Event (and Method when applicable)" section of "Workflow Action - Custom webhook". The text alongside this image reads: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw body editor. GET has no body; use Query Parameters to pass…. Immediately after, the guide continues: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.
- What to fill in: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw body editor. GET has no body; use Query Parameters to pass filters. The small tag icon next to fields opens the dynamic value picker (for example, {{contact.id}}).
- Controls: Event, CUSTOM, Method, Content-Type, Raw Body, POST, Body (Key and Value), GET, Query Parameters
- Next: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.

![Select the Event (and Method when applicable) (image 5 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391023/original/JyVoG0XaAdDiBdCMIE_qGJO4vO3YuSdYIA.png)

**Select the Event (and Method when applicable) (image 5 of 10)**

This screenshot appears in the "Select the Event (and Method when applicable)" section of "Workflow Action - Custom webhook". The text alongside this image reads: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw body editor. GET has no body; use Query Parameters to pass…. Immediately after, the guide continues: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.
- What to fill in: Choose the Event that matches your use case. CUSTOM reveals the Method picker (GET, POST, PUT, DELETE), Content-Type, and a Raw Body editor for JSON or other formats. POST provides a simple Body (Key and Value) interface without a raw body editor. GET has no body; use Query Parameters to pass filters. The small tag icon next to fields opens the dynamic value picker (for example, {{contact.id}}).
- Controls: Event, CUSTOM, Method, Content-Type, Raw Body, POST, Body (Key and Value), GET, Query Parameters
- Next: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.

### **Enter the URL**

Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.

![Enter the URL (image 6 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391209/original/koqeFYqfE2cjsgJ-GggSa9u2J4CN3zj_0Q.png)

**Enter the URL (image 6 of 10)**

This screenshot appears in the "Enter the URL" section of "Workflow Action - Custom webhook". The text alongside this image reads: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record. Immediately after, the guide continues: Select the authentication method required by the provider— Bearer Token, API Key, Basic Auth, OAuth2, or None (with custom headers)—and supply credentials exactly as specified to avoid 401/403 errors.
- What to copy: Paste your provider’s endpoint and include variables in the path when needed, such as https://api.example.com/leads/{{contact.id}}, so each request targets the correct record.
- Next: Select the authentication method required by the provider— Bearer Token, API Key, Basic Auth, OAuth2, or None (with custom headers)—and supply credentials exactly as specified to avoid 401/403 errors.

### **Choose Authorization**

Select the authentication method required by the provider—**Bearer Token**, **API Key**, **Basic Auth**, **OAuth2**, or **None** (with custom headers)—and supply credentials exactly as specified to avoid 401/403 errors.

![Choose Authorization (image 7 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391256/original/wffqrtLfdnPbdcrxh4jIKduKTetW4nFjUw.png)

**Choose Authorization (image 7 of 10)**

This screenshot appears in the "Choose Authorization" section of "Workflow Action - Custom webhook". The text alongside this image reads: Select the authentication method required by the provider— Bearer Token, API Key, Basic Auth, OAuth2, or None (with custom headers)—and supply credentials exactly as specified to avoid 401/403 errors. Immediately after, the guide continues: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized.
- What to choose: Select the authentication method required by the provider— Bearer Token, API Key, Basic Auth, OAuth2, or None (with custom headers)—and supply credentials exactly as specified to avoid 401/403 errors.
- Controls: Bearer Token, API Key, Basic Auth, OAuth2, None
- Next: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized.

### **Add Headers and Query Parameters (if needed)**

Provide required headers like **Content-Type**, **Authorization**, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized.

![Add Headers and Query Parameters (if needed) (image 8 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391899/original/5E42VGNcB9xSmInW79qF_9f2KM2dceWCeA.png)

**Add Headers and Query Parameters (if needed) (image 8 of 10)**

This screenshot appears in the "Add Headers and Query Parameters (if needed)" section of "Workflow Action - Custom webhook". The text alongside this image reads: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized. Immediately after, the guide continues: Enable response capture if it is available in your account to aid troubleshooting and record-keeping.
- What to fill in: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized.
- Controls: Content-Type, Authorization
- Next: Enable response capture if it is available in your account to aid troubleshooting and record-keeping.

![Add Headers and Query Parameters (if needed) (image 9 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391923/original/AnPUTd3sfl7O0czLwRfiEQ0fY1iL5yIASg.png)

**Add Headers and Query Parameters (if needed) (image 9 of 10)**

This screenshot appears in the "Add Headers and Query Parameters (if needed)" section of "Workflow Action - Custom webhook". The text alongside this image reads: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized. Immediately after, the guide continues: Enable response capture if it is available in your account to aid troubleshooting and record-keeping.
- What to fill in: Provide required headers like Content-Type, Authorization, and any custom keys, and add query parameters for GET filters or URL-based options; dynamic values such as email={{contact.email}} ensure each call is personalized.
- Next: Enable response capture if it is available in your account to aid troubleshooting and record-keeping.

### **Save response from this Webhook (optional)**

Enable response capture if it is available in your account to aid troubleshooting and record-keeping.

![Save response from this Webhook (optional) (image 10 of 10)](https://s3.amazonaws.com/cdn.freshdesk.com/data/helpdesk/attachments/production/155060391950/original/JffuOpTCujq23Ityc_ZX5-up2SSkRDsMMw.png)

**Save response from this Webhook (optional) (image 10 of 10)**

This screenshot appears in the "Save response from this Webhook (optional)" section of "Workflow Action - Custom webhook". The text alongside this image reads: Enable response capture if it is available in your account to aid troubleshooting and record-keeping. Immediately after, the guide continues: Click Save Action, trigger a test with a sample record or a sandbox endpoint such as Webhook.site or Postman, and review Execution Logs alongside provider logs to confirm status codes and payload shape before going live.
- What this covers: Enable response capture if it is available in your account to aid troubleshooting and record-keeping.
- Next: Click Save Action, trigger a test with a sample record or a sandbox endpoint such as Webhook.site or Postman, and review Execution Logs alongside provider logs to confirm status codes and payload shape before going live.

### **Save and test**

Click **Save Action**, trigger a test with a sample record or a sandbox endpoint such as Webhook.site or Postman, and review **Execution Logs** alongside provider logs to confirm status codes and payload shape before going live.

**Additional screenshot placeholders (add later if available):**

-   OAuth2 token management: Global Workflow Settings → OAuth2 / Manage Tokens (token redacted).
    
-   Execution Logs showing a successful 200 response.
    
-   Postman/Webhook.site confirming receipt of the payload.
    

---

## **Frequently Asked Questions**

**Q: Do I need a specific workflow trigger for Custom Webhook to work?**

No. Any workflow trigger can be used. Ensure your mapped variables (e.g., contact fields) exist at runtime.

**Q: My provider requires a static IP allowlist. Can GHL Customer Care provide one?**

No. Use header‑based authentication (Bearer/API Key/Basic/OAuth2) instead and share the required credentials with your provider.

**Q: Where do I put my API key header or query string?**

Prefer a header (e.g., X-API-Key). Only use query‑string keys if the provider specifically requires it.

**Q: Why am I getting 401/403 errors?**

Invalid or missing credentials, wrong auth type, expired token, or insufficient scopes/permissions. Re‑check Authorization and required headers.

**Q: The provider says my JSON is invalid (400/422). What should I check?**

Confirm **Content‑Type**, required fields, data types, and nested structure. Compare to the provider’s schema or run a Postman test.

**Q: Can I include arrays or nested objects in the payload?**

Yes. Build nested JSON or arrays and map dynamic values where needed (see examples above).

**Q: Can I capture and review the response?**

If available in your account, enable **Save response from this Webhook** and review the workflow’s **Execution Logs** and provider logs.

**Q: How do I decide between Custom Webhook and Webhook (Outbound)?**

Use **Custom Webhook** when you need advanced auth and flexible request building. Use **Webhook (Outbound)** for simpler, pre‑defined patterns.

---

Documentation for GHL Customer Care. Support: support@ghlcustomercare.com