> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deal-pipe.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Ad leads by webhook

> Receive leads from Meta, Google, LinkedIn or TikTok as inquiries through Zapier, Make or your own tool.

> [!NOTE]
>
> Ad leads need the extended CRM and activation by Dealpipe. Only admins set up connections.

Every lead your tool sends to Dealpipe becomes an inquiry under **CRM → Leads** right away. Dealpipe creates the contact or links it to an existing contact by email address. Routing rules, response time alerts and auto-replies run as for any other inquiry.

## Create a connection

1. Open **Settings → CRM → Ad leads**.
2. Choose **Add connection → Webhook** and enter a name, for example "Zapier Meta campaigns".
3. Copy the **URL** and the **secret**. The secret is shown only once.

The list shows the last lead received and the last error for each connection. From the row menu you can rename the connection, rotate its secret or delete it. After a rotation the old secret stops working at once. Deleting keeps the inquiries already received.

## Google Ads lead forms

Google Ads sends each lead from a lead form straight to Dealpipe, without Zapier or Make.

1. Open **Settings → CRM → Ad leads** and choose **Add connection → Google lead forms**.
2. Copy the **Webhook URL** and the **Webhook key**. The key is shown only once.
3. Open the lead form in Google Ads. Under **Export leads from Google Ads → Other data integration options → Webhook integration (optional)**, enter the URL and key.
4. Choose **Send test data**. Dealpipe creates a test inquiry without a contact; the connection shows the time and name of the last test lead. Then choose **Save**.

Real leads become inquiries with campaign, form and Google click ID. The same lead is never created twice, even when Google sends it again. After you rotate the key, enter the new key in every lead form.

Leads Google could not deliver while the connection was broken must be downloaded from Google Ads as a CSV. The CSV covers the last 30 days.

## Pause a connection

In the connection menu, choose **Pause**. A paused connection rejects every lead with `403` and stores nothing. **Resume** makes it accept leads again. Google does not resend leads from the pause; download them as a CSV.

## Send a lead

Send one `POST` request per lead with a JSON object to the connection URL. Put the secret in the `Authorization` header as a bearer token. Dealpipe also accepts the `X-Dealpipe-Secret` header.

```bash theme={null}
curl -X POST "https://app.deal-pipe.de/api/webhooks/leads/<CONNECTION-ID>" \
  -H "Authorization: Bearer <SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "lead_id": "meta-1234567890",
    "first_name": "Anna",
    "last_name": "Schmidt",
    "email": "anna.schmidt@example.com",
    "phone": "+49 170 1234567",
    "postal_code": "20095",
    "city": "Hamburg",
    "message": "Please call me back",
    "campaign": "New build Hafencity autumn",
    "ad_set": "Investors 30-55",
    "ad": "Penthouse video",
    "answers": { "Budget": "400,000 to 600,000 EUR", "Financing arranged": "Yes" }
  }'
```

### Fields

| Field | Required | Meaning |
| - | - | - |
| `lead_id` | Yes | Unique ID of the lead on the ad platform. Dealpipe creates one inquiry per ID. |
| `email` | No | Email address. Used to find an existing contact. |
| `phone` | No | Phone number. |
| `name` | No | Full name. Or use `first_name` and `last_name`. |
| `first_name`, `last_name` | No | First and last name when `name` is missing. |
| `postal_code`, `city` | No | Postal code and city. Routing rules can assign by postal code. |
| `message` | No | Free text from the lead. |
| `campaign`, `ad_set`, `ad` | No | Campaign, ad set and ad. Stored as the source of a new contact. |
| `utm_source`, `utm_medium`, `utm_content` | No | UTM values. Stored as the source of a new contact. |
| `is_test` | No | `true` marks a test lead. It is saved as an inquiry but creates no contact and triggers no routing, response time alert or auto-reply. |
| `answers` | No | Other form answers as an object of question and answer. They appear in the inquiry message. |

Empty values (`""` or `null`) count as missing. Numbers in text fields are kept as text. Dealpipe ignores other fields. Source details are stored only for a newly created contact; an existing contact keeps its first source.

### Responses

| Status | Meaning |
| - | - |
| `200` | Saved. The body holds `id` (the inquiry) and `duplicate`. `duplicate: true` means this `lead_id` arrived before and nothing new was created. |
| `400` | Invalid data. `error.field` names the field and `error.message` the reason. The error also shows in settings. |
| `401` | Unknown connection or wrong secret. Nothing was saved. |
| `403` | The connection is paused or ad leads are not active for your organization. `error.code` names the reason. Retrying does not help. |
| `413` | The request is larger than 64 KB. |
| `429` | More than 120 leads per minute to this connection. Wait the seconds given in the `Retry-After` header. |

You can safely resend a lead after an error. Because of `lead_id`, no duplicate inquiry is created.

## Example: Zapier

1. Choose your ad platform as the trigger, for example **Facebook Lead Ads → New Lead**.

2. Add the action **Webhooks by Zapier → Custom Request**.

3. Set **Method** to `POST` and **URL** to the connection URL.

4. Enter the JSON under **Data** and insert the trigger fields, for example:

   ```json theme={null}
   {
     "lead_id": "{{Lead ID}}",
     "email": "{{Email}}",
     "name": "{{Full Name}}",
     "phone": "{{Phone Number}}",
     "campaign": "{{Campaign Name}}",
     "ad_set": "{{Ad Set Name}}",
     "ad": "{{Ad Name}}"
   }
   ```

5. Under **Headers**, add `Authorization` with the value `Bearer <SECRET>` and `Content-Type` with the value `application/json`.

6. Test the step. The lead appears under **CRM → Leads**.

## Example: Make

1. Choose your ad platform as the trigger, for example **Facebook Lead Ads → Watch Leads**.
2. Add the module **HTTP → Make a request**.
3. Set **URL** to the connection URL and **Method** to `POST`.
4. Under **Headers**, add `Authorization` with the value `Bearer <SECRET>`.
5. Choose `Raw` as **Body type** and `JSON (application/json)` as **Content type**.
6. Enter the JSON under **Request content** and insert the trigger fields, as in the Zapier example.
7. Run the scenario once. The lead appears under **CRM → Leads**.

> [!TIP]
>
> To test, send `"is_test": true`. The inquiry appears under **CRM → Leads**, without a contact, routing or auto-reply.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.