Advanced7 min

Webhook API

Receive real-time notifications when events occur. Build reactive integrations with webhook callbacks.

Overview

What Are Webhooks?

Webhooks push data to your server when events happen:

  • Workflow executed
  • Form submitted
  • Integration connected
  • Error occurred

How They Work

Event occurs → Our server → POST to your URL → Your server processes

Setting Up Webhooks

Create Webhook

  1. Go to Settings > Webhooks
  2. Click Create Webhook
  3. Enter your endpoint URL
  4. Select events to receive
  5. Save

Via API

POST /webhooks
{
  "url": "https://yoursite.com/webhook",
  "events": ["workflow.executed", "form.submitted"],
  "secret": "your-webhook-secret"
}

Webhook Events

Workflow Events

| Event | Description | |-------|-------------| | workflow.created | New workflow created | | workflow.updated | Workflow modified | | workflow.published | Workflow published | | workflow.deleted | Workflow deleted | | workflow.executed | Execution completed | | workflow.failed | Execution failed |

Form Events

| Event | Description | |-------|-------------| | form.created | New form created | | form.updated | Form modified | | form.submitted | Form submission received |

Integration Events

| Event | Description | |-------|-------------| | integration.connected | New integration connected | | integration.disconnected | Integration removed | | integration.error | Integration error |

Team Events

| Event | Description | |-------|-------------| | member.invited | Team invite sent | | member.joined | Member accepted invite | | member.removed | Member removed |

Webhook Payload

Payload Structure

{
  "id": "evt_123abc",
  "event": "workflow.executed",
  "created_at": "2024-01-20T15:30:00Z",
  "data": {
    "workflow_id": "wf_456",
    "execution_id": "exec_789",
    "status": "completed",
    "duration_ms": 1234,
    "output": {...}
  }
}

Common Fields

All payloads include:

  • id - Unique event ID
  • event - Event type
  • created_at - Timestamp
  • data - Event-specific data

Event Details

workflow.executed

{
  "event": "workflow.executed",
  "data": {
    "workflow_id": "wf_456",
    "workflow_name": "Lead Notification",
    "execution_id": "exec_789",
    "status": "completed",
    "trigger": "webhook",
    "started_at": "2024-01-20T15:30:00Z",
    "completed_at": "2024-01-20T15:30:05Z",
    "duration_ms": 5000,
    "input": {...},
    "output": {...}
  }
}

workflow.failed

{
  "event": "workflow.failed",
  "data": {
    "workflow_id": "wf_456",
    "execution_id": "exec_789",
    "status": "failed",
    "error": {
      "code": "NODE_ERROR",
      "message": "API returned 500",
      "node_id": "node_123"
    }
  }
}

form.submitted

{
  "event": "form.submitted",
  "data": {
    "form_id": "form_123",
    "form_name": "Contact Form",
    "submission_id": "sub_456",
    "submitted_at": "2024-01-20T15:30:00Z",
    "data": {
      "name": "John Doe",
      "email": "john@example.com",
      "message": "Hello!"
    }
  }
}

Security

Verifying Signatures

We sign all webhooks with HMAC-SHA256:

X-Webhook-Signature: sha256=abc123...

Verification Code

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook...
  res.status(200).send('OK');
});

Python Example

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected = 'sha256=' + hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(signature, expected)

Handling Webhooks

Best Practices

  1. Respond quickly - Return 200 within 5 seconds
  2. Process async - Queue for later processing
  3. Handle duplicates - Check event ID
  4. Verify signatures - Always validate

Example Handler

app.post('/webhook', async (req, res) => {
  // 1. Verify signature
  if (!verifySignature(req)) {
    return res.status(401).send('Invalid');
  }

  // 2. Check for duplicates
  const eventId = req.body.id;
  if (await isProcessed(eventId)) {
    return res.status(200).send('Already processed');
  }

  // 3. Queue for processing
  await queue.add('webhook', req.body);

  // 4. Respond immediately
  res.status(200).send('Accepted');
});

// Process async
queue.process('webhook', async (job) => {
  const event = job.data;

  switch (event.event) {
    case 'workflow.executed':
      await handleWorkflowExecuted(event.data);
      break;
    case 'form.submitted':
      await handleFormSubmitted(event.data);
      break;
  }

  await markProcessed(event.id);
});

Retry Policy

Automatic Retries

Failed deliveries are retried:

  • Retry 1: After 1 minute
  • Retry 2: After 5 minutes
  • Retry 3: After 30 minutes
  • Retry 4: After 2 hours
  • Retry 5: After 24 hours

Failure Conditions

We retry when:

  • Connection timeout (30s)
  • 5xx response codes
  • Connection refused

We don't retry when:

  • 2xx response (success)
  • 4xx response (client error)
  • Invalid URL

Monitoring

Webhook Logs

View delivery history:

  1. Go to Settings > Webhooks
  2. Click your webhook
  3. View Delivery Log

Log Details

Each delivery shows:

  • Event type
  • Payload
  • Response code
  • Response time
  • Retry count

Alerts

Set up alerts for:

  • Failed deliveries
  • High latency
  • Consecutive failures

Managing Webhooks

List Webhooks

GET /webhooks

Get Webhook Details

GET /webhooks/:id

Update Webhook

PATCH /webhooks/:id
{
  "events": ["workflow.executed"],
  "active": true
}

Delete Webhook

DELETE /webhooks/:id

Test Webhook

POST /webhooks/:id/test

Sends a test event to your endpoint.

Troubleshooting

Not Receiving Webhooks

  • Check URL is publicly accessible
  • Verify firewall allows our IPs
  • Check webhook is active
  • Review delivery logs

Invalid Signature

  • Check secret matches
  • Verify payload not modified
  • Check encoding (UTF-8)

Timeouts

  • Respond quickly (< 5s)
  • Process async
  • Optimize endpoint

Next Steps

Tags

apiwebhooksevents