Simulations

Overview

Webhook simulation allows you to test your integration without triggering real business processes or affecting production data. Simulated events work exactly like production webhooks but are clearly marked so you can handle them differently.

  • Safe Testing: Test without affecting real data
  • Production-Like: Uses same infrastructure as real events
  • Easy Debugging: Validate configuration before going live

Why Simulate Webhooks?

Ensure your webhook endpoint is configured correctly:

  • URL is accessible
  • Signature verification works
  • Response time is acceptable
  • Error handling is robust

Verify your application handles events correctly:

  • Events are parsed properly
  • Business logic executes as expected
  • Database updates work correctly
  • No side effects in production systems

Troubleshoot problems safely:

  • Reproduce error conditions
  • Test edge cases
  • Verify fixes without risk
  • Check logs and monitoring

Help developers understand the integration:

  • See real webhook payloads
  • Learn event structures
  • Practice responding to events
  • Build confidence before production

How Simulation Works

When you simulate a webhook event:

  1. Deel sends a test payload to your configured endpoint
  2. The payload is marked with "is_simulation": true
  3. Same authentication and retry logic applies as production
  4. Event is logged in webhook delivery history
  5. Your endpoint receives a realistic test event

Simulated events use the same infrastructure as production webhooks, so they’re an accurate test of your integration’s reliability.

Simulating Events in Developer Center

2

Select your webhook

Click on the webhook subscription you want to test

3

View subscribed events

In the webhook details page, you’ll see all events you’re subscribed to

4

Expand event type

Expand the event type you want to simulate

5

Click Simulate

Click the Simulate button next to the event. A dialog appears confirming the simulation was successful.

6

Verify delivery

Check your endpoint logs to confirm the webhook was received

Quick testing tip: Keep the Developer Center open while testing your local endpoint with ngrok. You can simulate events instantly and see results in real-time.

Simulated Event Payload

Simulated webhooks include the is_simulation flag in the payload:

1{
2 "data": {
3 "meta": {
4 "event_type": "contract.created",
5 "organization_id": "org_abc123",
6 "event_id": "evt_sim_xyz789",
7 "occurred_at": "2025-02-05T15:39:38.070Z",
8 "is_simulation": true // ← Simulation flag
9 },
10 "resource": [
11 {
12 "contract_id": "ctr_test_123",
13 "worker_email": "test.worker@example.com",
14 "status": "pending",
15 "type": "eor",
16 "country": "US"
17 }
18 ]
19 },
20 "timestamp": "2025-02-05T15:39:38.070Z"
21}

Handling Simulated Events

You can detect and handle simulated events differently in your code:

1app.post('/webhooks/deel', async (req, res) => {
2 const { meta } = req.body.data;
3 const resource = req.body.data.resource[0];
4
5 // Check if this is a simulation
6 if (meta.is_simulation) {
7 console.log('📋 Received simulated event:', meta.event_type);
8
9 // Log but don't process
10 await logSimulatedEvent(meta.event_type, resource);
11
12 return res.status(200).send('Simulation received');
13 }
14
15 // Process real events normally
16 await processEvent(meta.event_type, resource);
17
18 res.status(200).send('OK');
19});

Important: Always check the is_simulation flag to avoid processing test data as if it were real. This prevents duplicate records, incorrect metrics, and unintended side effects.

Best Practices

Simulate each event type you’re subscribed to:

1const eventsToTest = [
2 'contract.created',
3 'contract.signed',
4 'payment.completed'
5];
6
7// Test each one in Developer Center
8eventsToTest.forEach(event => {
9 console.log(`✓ Test ${event}`);
10});

Always verify:

  • Event was received
  • Status code is correct
  • Response time is acceptable
  • No errors in your application logs

Use realistic test data that mirrors your production use cases:

  • Actual country codes
  • Valid email formats
  • Realistic contract amounts
  • Expected date formats

Test unusual scenarios:

  • Very long field values
  • Special characters in names
  • Multiple resources in array
  • Missing optional fields

Don’t process simulated events as real data:

1if (meta.is_simulation) {
2 // Log, validate, test - but don't create real records
3 await validateWebhookStructure(resource);
4 await testBusinessLogic(resource);
5 return;
6}
7
8// Only process real events
9await createDatabaseRecords(resource);

Troubleshooting Simulations

Check:

  • Is your endpoint accessible?
  • Is the webhook enabled?
  • Did you hit the rate limit (10/hour)?
  • Is your server responding to requests?

Test connectivity:

$curl -X POST https://your-endpoint.com/webhooks/deel \
> -H "Content-Type: application/json" \
> -d '{"test": "data"}'

Possible causes:

  • Your code rejects simulated events
  • Different validation for test data
  • Sandbox vs production environment mismatch

Solution: Ensure simulated events can pass through your validation:

1// Allow both real and simulated events
2if (!meta.is_simulation) {
3 // Only validate real events strictly
4 await strictValidation(resource);
5}

Options:

  1. Create additional webhook subscriptions for testing
  2. Use webhook logs to replay past events
  3. Retrieve sample payloads from API and test locally
  4. Use the event structure documentation to build test payloads

Local testing:

1// Create test payload locally
2const testPayload = {
3 data: {
4 meta: {
5 event_type: 'contract.created',
6 is_simulation: true
7 },
8 resource: [{ /* test data */ }]
9 }
10};
11
12// Test your handler
13await handleWebhook(testPayload);

Additional Resources