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

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

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
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

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: