BrightshoalDocsOpen console
MenuWebhooks

API reference

Webhooks

Subscribe an HTTPS endpoint to events (calls ending, messages, leads) and inspect every delivery attempt.

Create a webhook subscription

POST/api/webhooks

Subscribes an HTTPS endpoint to events in one project. Each delivery is a JSON POST signed with X-Webhook-Signature: sha256=<hex HMAC-SHA256 of the raw body, keyed with the secret>; answer with any 2xx within 10 seconds. The response carries the signing secret this once: store it. Send your own secret, or one is minted for you. Event types: call.started, call.connected, call.ended, conversation.started, conversation.message.created, conversation.handoff_requested, conversation.callback_requested, conversation.takeover.started, conversation.takeover.released, conversation.analyzed, conversation.ended, lead.captured.

Secret API key, not read-only. How it works

Request body

  • project_idstring

    Required only for an org-wide key.

  • urlstringrequireduri

    Public HTTPS destination. Private addresses and redirects are refused at delivery.

  • eventsarray of string

    Event types to deliver; empty or omitted means all. An unknown name is refused with 400.

  • modestring

    Which chats it hears about. It cannot be changed later: create a new subscription instead.

    One of live test

    Default "live"

  • secretstringnot empty

    Optional; a whsec_… secret is minted when omitted.

  • enabledboolean

    False creates the subscription turned off. Default true.

Returns

201 OK

Response attributes
  • dataWebhookSubscriptionCreatedrequired

    A new subscription, with its signing secret. This is the only response that shows the secret.

    10 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • urlstringrequireduri

      Public HTTPS destination. Private addresses and redirects are refused at delivery.

    • eventsarray of stringrequired

      Subscribed event types; empty = all.

    • modestring

      live hears about live chats and calls; test only about test chats (test keys and the console's test chat) and test calls (mode test, test numbers, the console's test call), whose events carry livemode: false. Fixed at creation.

      One of live test

    • disabled_atstring | nullISO 8601 timestamp

      Set while the subscription is turned off.

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

    • secretstringrequired

      HMAC-SHA256 signing key (whsec_ and 48 hex characters when minted). Verify each delivery by computing the HMAC of the raw body with this whole string as the key.

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
POST /api/webhooks
curl -X POST "https://api.myleadsfactory.tech/api/webhooks" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://hooks.acmetravel.com/mlf",
  "events": [
    "call.ended",
    "lead.captured"
  ],
  "project_id": "proj_2f9c41d0a8b34e6f9d1c7a5b3e8f0a12"
}'
Response 201
{
  "data": {
    "id": "whsub_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "url": "https://example.com/hook",
    "events": [
      "string"
    ],
    "mode": "live",
    "disabled_at": "2026-10-28T09:30:00.000Z",
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z",
    "secret": "whsec_..."
  }
}

List webhook subscriptions

GET/api/webhooks

Subscriptions in scope, without their signing secrets (a secret is shown only when the subscription is created).

Secret API key. How it works

Query parameters

  • project_idstring

    Only this project's subscriptions.

Returns

200 OK

Response attributes
  • dataarray of WebhookSubscriptionrequired

    9 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • urlstringrequireduri

      Public HTTPS destination. Private addresses and redirects are refused at delivery.

    • eventsarray of stringrequired

      Subscribed event types; empty = all.

    • modestring

      live hears about live chats and calls; test only about test chats (test keys and the console's test chat) and test calls (mode test, test numbers, the console's test call), whose events carry livemode: false. Fixed at creation.

      One of live test

    • disabled_atstring | nullISO 8601 timestamp

      Set while the subscription is turned off.

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/webhooks
curl "https://api.myleadsfactory.tech/api/webhooks" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "whsub_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "url": "https://example.com/hook",
      "events": [
        "string"
      ],
      "mode": "live",
      "disabled_at": "2026-10-28T09:30:00.000Z",
      "created_at": "2026-10-28T09:30:00.000Z",
      "updated_at": "2026-10-28T09:30:00.000Z"
    }
  ]
}

Get a webhook subscription

GET/api/webhooks/{id}

One subscription, without its signing secret.

Secret API key. How it works

Path parameters

  • idstringrequired

    Subscription id, whsub_....

Returns

200 OK

Response attributes
  • dataWebhookSubscriptionrequired

    9 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • urlstringrequireduri

      Public HTTPS destination. Private addresses and redirects are refused at delivery.

    • eventsarray of stringrequired

      Subscribed event types; empty = all.

    • modestring

      live hears about live chats and calls; test only about test chats (test keys and the console's test chat) and test calls (mode test, test numbers, the console's test call), whose events carry livemode: false. Fixed at creation.

      One of live test

    • disabled_atstring | nullISO 8601 timestamp

      Set while the subscription is turned off.

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/webhooks/{id}
curl "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "whsub_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "url": "https://example.com/hook",
    "events": [
      "string"
    ],
    "mode": "live",
    "disabled_at": "2026-10-28T09:30:00.000Z",
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Update a webhook subscription

PATCH/api/webhooks/{id}

Change the URL, the events, the secret, or turn the subscription off and on. Send at least one field. A new secret applies to the next attempt, including retries already queued; it is not echoed back.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Subscription id, whsub_....

Request body

  • urlstringuri

    Public HTTPS destination. Private addresses and redirects are refused at delivery.

  • eventsarray of string

    Replaces the event list; empty means all. An unknown name is refused with 400.

  • secretstringnot empty

    A new signing secret. Write-only.

  • enabledboolean

    False turns deliveries off; true turns them back on.

  • modestring

    Accepted only when it is the subscription's current mode, so a read can be sent back; a change is refused.

    One of live test

Returns

200 OK

Response attributes
  • dataWebhookSubscriptionrequired

    9 attributes
    • idstringrequired

    • org_idstringrequired

    • project_idstringrequired

    • urlstringrequireduri

      Public HTTPS destination. Private addresses and redirects are refused at delivery.

    • eventsarray of stringrequired

      Subscribed event types; empty = all.

    • modestring

      live hears about live chats and calls; test only about test chats (test keys and the console's test chat) and test calls (mode test, test numbers, the console's test call), whose events carry livemode: false. Fixed at creation.

      One of live test

    • disabled_atstring | nullISO 8601 timestamp

      Set while the subscription is turned off.

    • created_atstringISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
PATCH /api/webhooks/{id}
curl -X PATCH "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID" \
  -H "Authorization: Bearer $MLF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled": false
}'
Response 200
{
  "data": {
    "id": "whsub_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "org_id": "org_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "url": "https://example.com/hook",
    "events": [
      "string"
    ],
    "mode": "live",
    "disabled_at": "2026-10-28T09:30:00.000Z",
    "created_at": "2026-10-28T09:30:00.000Z",
    "updated_at": "2026-10-28T09:30:00.000Z"
  }
}

Delete a webhook subscription

DELETE/api/webhooks/{id}

Stops deliveries for good, including retries still pending, and deletes the subscription's delivery log.

Secret API key, not read-only. How it works

Path parameters

  • idstringrequired

    Subscription id, whsub_....

Returns

200 OK

Response attributes
  • dataDeleteResultrequired

    2 attributes
    • idstringrequired

    • deletedbooleanrequired

  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 403 Refused, for example a read-only key on a write (read_only_key), a role too low for the route (insufficient_role), or a route that needs a console session
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
DELETE /api/webhooks/{id}
curl -X DELETE "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": {
    "id": "id_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
    "deleted": true
  }
}

List a subscription's recent deliveries

GET/api/webhooks/{id}/deliveries

The latest 100 deliveries, newest first: one row per event, with the cumulative attempts and the latest attempt's status and error, without the event body. Each event is tried up to 10 times with backoff from 10 seconds (about 85 minutes in all). failed means it never got a 2xx: every attempt failed, the subscription was turned off meanwhile, or it was still pending after 24 hours.

Secret API key. How it works

Path parameters

  • idstringrequired

    Subscription id, whsub_....

Query parameters

  • statusstring

    Only deliveries in this state.

    One of pending delivered failed

Returns

200 OK

Response attributes
  • dataarray of WebhookDeliveryrequired

    13 attributes
    • idstringrequired

    • event_idstringrequired

    • subscription_idstringrequired

    • project_idstring

    • eventstringrequired

    • statusstringrequired

      One of pending delivered failed

    • attemptsintegerrequired

    • last_statusinteger | null

      HTTP status of the latest attempt.

    • last_errorstring | null

    • last_attempt_atstring | nullISO 8601 timestamp

    • delivered_atstring | nullISO 8601 timestamp

    • created_atstringrequiredISO 8601 timestamp

    • updated_atstringISO 8601 timestamp

  • 400 Validation error: usually invalid_request, with the failing fields in issues when there are any
  • 401 Missing, malformed, unknown or revoked API key (unauthorized)
  • 404 Not found, or outside what the key can see
  • 429 Rate limit exceeded (rate_limited). Wait Retry-After seconds. Budgets are per 60-second window: developer API 120 per key and 600 per organization; public chat 30 per IP address, except polling for updates (60 per conversation and IP address) and analytics events (120 per IP address).
GET /api/webhooks/{id}/deliveries
curl "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID/deliveries" \
  -H "Authorization: Bearer $MLF_API_KEY"
Response 200
{
  "data": [
    {
      "id": "whdl_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "event_id": "evt_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "subscription_id": "whsub_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "project_id": "proj_5f0c2a9e7b1d4c3e8a6f0b2d4c6e8a1f",
      "event": "string",
      "status": "pending",
      "attempts": 1,
      "last_status": 1,
      "last_error": "string",
      "last_attempt_at": "2026-10-28T09:30:00.000Z",
      "delivered_at": "2026-10-28T09:30:00.000Z",
      "created_at": "2026-10-28T09:30:00.000Z",
      "updated_at": "2026-10-28T09:30:00.000Z"
    }
  ]
}