> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.deel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.deel.com/_mcp/server.

# Introduction

> Real-time notifications for key platform events

## Overview

Deel Webhooks deliver real-time notifications for key platform events, allowing you to build efficient and responsive integrations without relying on constant polling.

* **Real-time Updates:** Receive notifications as events occur
* **Secure Delivery:** Every payload is signed using SHA256
* **Flexible Subscriptions:** Manage webhook subscriptions via API or Developer Center

## Use Cases

Here are a few examples of how you might use webhooks:

#### Syncing Data

Automatically update your system when new contracts are created or modified in Deel.

#### Real-time Notifications

Trigger alerts or workflows in your internal tools when important events happen.

#### Workflow Automation

Start external processes based on specific events like contract signatures or payment completions.

## Webhooks vs Polling

Choosing between webhooks and polling depends on your application's requirements for data timeliness and resource efficiency.

#### When to use webhooks

**Recommended for:**

* Applications requiring immediate notification when an event occurs
* Reducing unnecessary API requests and server load
* Event-driven architectures that can process asynchronous HTTP callbacks

**Characteristics:**

* Server pushes event data to your endpoint when triggered
* Near real-time delivery with minimal delay
* More efficient for infrequent or unpredictable updates
* Endpoint setup and secure handling required

#### When to use polling

**Recommended for:**

* One-time or scheduled initial data sync to align systems before using webhooks
* Backup solution when webhook delivery is not possible due to technical limitations
* Legacy systems unable to receive incoming HTTP requests
* Critical scenarios where you need redundancy in event delivery

**Characteristics:**

* Client periodically checks the API for new data at scheduled intervals
* Events are not detected in real time—there is inherent delay based on the polling interval
* Increased server load and API usage compared to webhooks
* Simpler infrastructure—public endpoints are not required

Polling should not be used as the primary method for receiving updates from Deel. Always use webhooks when possible to ensure real-time, efficient, and reliable event notification.

### Comparison

| Method       | When to Use                          | Characteristics                 |
| ------------ | ------------------------------------ | ------------------------------- |
| **Polling**  | Frequent updates, non-real-time      | Resource-intensive, predictable |
| **Webhooks** | Infrequent updates, real-time needed | Efficient, event-triggered      |

## How Webhooks Work

When an event occurs in your Deel account, Deel sends an HTTP POST request to your configured endpoint with details about what happened.

### Webhook structure

Each webhook request contains:

#### Headers

Every webhook includes these HTTP headers:

| Header                   | Purpose                                                  |
| ------------------------ | -------------------------------------------------------- |
| `x-deel-signature`       | HMAC-SHA256 signature for verifying payload authenticity |
| `x-deel-hmac-label`      | Identifies which signing key was used                    |
| `x-deel-webhook-version` | API version used for serialization                       |

#### Payload

The JSON payload structure:

```json
{
  "data": {
    "meta": {
      "event_type": "contract.created",
      "organization_id": "your-org-id"
    },
    "resource": [
      {
        // Event-specific data
      }
    ]
  },
  "timestamp": "2025-02-05T15:39:38.070Z"
}
```

**Payload components:**

* `meta`: Event metadata (type, organization details)
* `resource`: Event-specific data (varies by event type)
* `timestamp`: When the event occurred (ISO 8601)

#### Security

Webhooks are secured using HMAC-SHA256 signatures:

1. Deel generates a signature using your webhook's secret key
2. The signature is sent in the `x-deel-signature` header
3. Your endpoint verifies the signature matches the payload

**Signature computation:**

```
HMAC-SHA256(signing_key, "POST" + raw_payload_body)
```

Always verify signatures before processing webhooks to prevent malicious requests.

## Available Events

Deel supports a wide range of webhook events across different services.

**Get the complete list**: Use the `GET /webhooks/events/types` API endpoint to retrieve all available event types and their descriptions.

## Webhook Reliability

Deel ensures webhook delivery through an automatic retry mechanism:

### Retry behavior

If your endpoint fails to respond with a 2xx status code, Deel will retry delivery:

| Attempt      | Delay      | Status                    |
| ------------ | ---------- | ------------------------- |
| 1st retry    | 1 minute   | Active                    |
| 2nd retry    | 2 minutes  | Active                    |
| 3rd retry    | 4 minutes  | Active                    |
| 4th retry    | 8 minutes  | Active                    |
| 5th retry    | 16 minutes | Active                    |
| 6th retry    | 32 minutes | Active                    |
| 7th retry    | 1 hour     | Active                    |
| 8th retry    | 2 hours    | Active                    |
| 9th retry    | 4 hours    | Active                    |
| 10th attempt | 16 hours   | Webhook disabled if fails |

After **10 consecutive failures**, the webhook subscription is automatically disabled. You'll need to re-enable it manually through the API or Developer Center.

### What counts as a failure?

* Non-2xx HTTP status code (400, 401, 403, 500, etc.)
* Connection timeout (endpoint doesn't respond within 30 seconds)
* Network errors or unreachable endpoint

## Best Practices

#### Respond quickly

Return a `200 OK` response within 30 seconds (ideally under 5 seconds).

**Why?** Prevents timeouts and retry storms. Process webhooks asynchronously if needed:

```javascript
app.post('/webhooks', async (req, res) => {
  // Immediately acknowledge
  res.status(200).send('OK');

  // Process asynchronously
  await queue.add('process-webhook', req.body);
});
```

#### Handle duplicate events

Webhooks may be delivered more than once due to network issues or retries.

**Solution:** Make your handlers idempotent by tracking processed event IDs:

```javascript
const eventId = webhook.data.meta.event_id;

if (await db.isProcessed(eventId)) {
  return; // Already processed
}

await processEvent(webhook);
await db.markProcessed(eventId);
```

#### Subscribe selectively

Only subscribe to events your application needs.

**Why?** Reduces unnecessary traffic and processing. You can always add more events later.

#### Implement reconciliation

Don't rely solely on webhooks. Run periodic reconciliation jobs to catch any missed events:

```javascript
// Daily sync to catch any gaps
cron.schedule('0 0 * * *', async () => {
  const lastSync = await getLastSyncTime();
  const updates = await deelAPI.get('/contracts', {
    params: { updated_after: lastSync }
  });
  await reconcileData(updates);
});
```

## Get Started

Ready to set up webhooks? Choose your path:

#### [Webhooks Quickstart](/api/webhooks/quickstart)

Programmatic setup with code examples in multiple languages

#### [No Code](/api/webhooks/no-code)

Set up webhooks using the visual Developer Center interface