Introduction

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:

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

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

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

Webhooks vs Polling

Understanding when to use webhooks versus polling helps you build more efficient integrations.

When to Use Polling

Use polling if:

  • Updates are frequent
  • You don’t need updates in real-time

Characteristics:

  • Resource-intensive
  • Predictable load
  • Simpler to implement
When to Use Webhooks

Use webhooks if:

  • Updates are infrequent
  • You need updates in real-time

Characteristics:

  • Efficient, event-triggered
  • Lower API usage
  • Requires endpoint setup

Comparison

MethodWhen to UseCharacteristics
PollingFrequent updates, non-real-timeResource-intensive, predictable
WebhooksInfrequent updates, real-time neededEfficient, 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:

Every webhook includes these HTTP headers:

HeaderPurpose
x-deel-signatureHMAC-SHA256 signature for verifying payload authenticity
x-deel-hmac-labelIdentifies which signing key was used
x-deel-webhook-versionAPI version used for serialization

Available Events

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

Get the complete list: Use the GET /webhooks/events 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:

AttemptDelayStatus
1st retry1 minuteActive
2nd retry2 minutesActive
3rd retry4 minutesActive
4th retry8 minutesActive
5th retry16 minutesActive
6th retry32 minutesActive
7th retry1 hourActive
8th retry2 hoursActive
9th retry4 hoursActive
10th attempt16 hoursWebhook 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

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

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

1app.post('/webhooks', async (req, res) => {
2 // Immediately acknowledge
3 res.status(200).send('OK');
4
5 // Process asynchronously
6 await queue.add('process-webhook', req.body);
7});

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

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

1const eventId = webhook.data.meta.event_id;
2
3if (await db.isProcessed(eventId)) {
4 return; // Already processed
5}
6
7await processEvent(webhook);
8await db.markProcessed(eventId);

Only subscribe to events your application needs.

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

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

1// Daily sync to catch any gaps
2cron.schedule('0 0 * * *', async () => {
3 const lastSync = await getLastSyncTime();
4 const updates = await deelAPI.get('/contracts', {
5 params: { updated_after: lastSync }
6 });
7 await reconcileData(updates);
8});

Get Started

Ready to set up webhooks? Choose your path: