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

# How Webhooks Work

> The recommended way to receive enrichment results

<Info>
  If you're using **Zapier, Make, Clay, or n8n**, webhooks are handled automatically by these platforms. You can skip this section.
</Info>

The Enrich API and Reverse Email Lookup are **asynchronous**. This means when you start an operation, the API returns immediately with an ID, and results are delivered later via webhook.

<img src="https://mintcdn.com/fullenrich/QlQ00joQ41SH1_-N/images/async-schema.svg?fit=max&auto=format&n=QlQ00joQ41SH1_-N&q=85&s=8bcb5e361d145227592369a31b598a1f" alt="Async Schema" width="2125" height="593" data-path="images/async-schema.svg" />

## Why Webhooks?

Webhooks are notifications sent directly to your server when results are ready. Instead of you having to check for results, we push them to you immediately.

**Benefits:**

* **Fastest method** to receive results
* No need to keep a connection open
* No HTTP timeouts or retries to manage
* Simpler and more reliable than polling

## How It Works

1. When you start an enrichment or reverse lookup, include a `webhook_url` in your request
2. We process your contacts (typically 30-90 seconds per contact)
3. When done, we POST the results directly to your webhook URL

The content sent to your webhook is the same as what you'd get from the GET endpoint.

## Webhook Parameters

### `webhook_url` — Batch Completion

Your webhook URL receives a POST request when the **entire batch** is finished, lacks credits, or is canceled.

```json theme={null}
{
  "name": "My Enrichment",
  "webhook_url": "https://your-server.com/webhook",
  "data": [...]
}
```

## Reliability & Retries

Webhooks are reliable by design. If we can't deliver your result (for example, receiving a non-2xx status code), we'll automatically **retry every minute, up to 5 times**.

For most use cases, you can treat webhooks as "guaranteed delivery." If there's ever a question about a specific result or missed event, our team can check our delivery logs on request.

## Tracking Requests with `custom`

You can easily keep track of which result belongs to which user or request by using the `custom` parameter. Include any identifier you need (User ID, CRM contact ID, etc.), and it will be returned exactly as provided in the webhook payload.

```json theme={null}
{
  "data": [
    {
      "first_name": "John",
      "last_name": "Doe",
      "domain": "example.com",
      "custom": {
        "user_id": "12584",
        "crm_contact_id": "abc-123"
      }
    }
  ]
}
```

<Note>
  Custom field values must be strings. Numbers will return an error.
</Note>

## Testing Webhooks

<Tip>
  A quick way to test webhooks and see the payload structure is to use [**webhook.site**](https://webhook.site) — a free service that gives you a temporary URL to receive and inspect webhook requests.
</Tip>

## Polling (Not Recommended)

Polling means repeatedly calling the GET endpoint to check if the operation is finished. This is **not recommended** because:

* It consumes your rate limit quota
* Results come slower than with webhooks
* More complex to implement reliably

If you must use polling, don't poll more than once every 5-10 minutes. Never poll every few seconds.

## Real-Time Webhook Events

### `webhook_events.contact_finished`

If you need results as fast as possible, use this parameter. It fires a webhook **immediately after each individual contact** is enriched, without waiting for the entire batch to complete.

This is perfect for real-time integrations where you want to process results as they come in.

```json theme={null}
{
  "name": "My Enrichment",
  "webhook_url": "https://your-server.com/webhook/batch-complete",
  "webhook_events": {
    "contact_finished": "https://your-server.com/webhook/single-contact"
  },
  "data": [...]
}
```

<Tip>
  You can use both `webhook_url` and `webhook_events.contact_finished` together. You'll receive a webhook for each contact as it completes, plus a final webhook when the entire batch is done.
</Tip>

### Event Payload

The webhook receives the enriched profile immediately after processing. The payload follows the standard response format with a single contact in the `data` array:

```json theme={null}
{
  "id": "<string>",
  "name": "<string>",
  "status": "IN_PROGRESS",
  "cost": {
    "credits": 10
  },
  "data": [
    {
      "input": {
        "first_name": "<string>",
        "last_name": "<string>",
        "full_name": "<string>",
        "company_domain": "<string>",
        "company_name": "<string>",
        "professional_network_url": "<string>"
      },
      "custom": {},
      "contact_info": {
        "most_probable_work_email": {
          "email": "<string>",
          "status": "DELIVERABLE"
        },
        "most_probable_personal_email": {
          "email": "<string>",
          "status": "DELIVERABLE"
        },
        "most_probable_phone": {
          "number": "<string>",
          "region": "<string>"
        },
        "work_emails": [
          {
            "email": "<string>",
            "status": "DELIVERABLE"
          }
        ],
        "personal_emails": [
          {
            "email": "<string>",
            "status": "DELIVERABLE"
          }
        ],
        "phones": [
          {
            "number": "<string>",
            "region": "<string>"
          }
        ]
      },
      "profile": {
        "id": "<string>",
        "full_name": "<string>",
        "first_name": "<string>",
        "last_name": "<string>",
        "location": {
          "country": "<string>",
          "country_code": "<string>",
          "city": "<string>",
          "region": "<string>"
        },
        "social_profiles": { ... },
        "educations": [{ ... }],
        "languages": [{ ... }],
        "skills": ["<string>"],
        "employment": { ... }
      }
    }
  ]
}
```

<Note>
  The `status` will be `IN_PROGRESS` since individual contacts are sent as they complete, before the entire batch finishes.
</Note>
