API reference
Webhooks
Subscribe an HTTPS endpoint to events (calls ending, messages, leads) and inspect every delivery attempt.
- POST
/api/webhooksCreate a webhook subscription - GET
/api/webhooksList webhook subscriptions - GET
/api/webhooks/{id}Get a webhook subscription - PATCH
/api/webhooks/{id}Update a webhook subscription - DELETE
/api/webhooks/{id}Delete a webhook subscription - GET
/api/webhooks/{id}/deliveriesList a subscription's recent deliveries
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_idstringRequired only for an org-wide key.
urlstringrequireduriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringEvent types to deliver; empty or omitted means all. An unknown name is refused with 400.
modestringWhich chats it hears about. It cannot be changed later: create a new subscription instead.
One of
livetestDefault
"live"secretstringnot emptyOptional; a whsec_… secret is minted when omitted.
enabledbooleanFalse creates the subscription turned off. Default true.
Returns
201 OK
Response attributes
dataWebhookSubscriptionCreatedrequiredA new subscription, with its signing secret. This is the only response that shows the secret.
10 attributes
idstringrequiredorg_idstringrequiredproject_idstringrequiredurlstringrequireduriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringrequiredSubscribed event types; empty = all.
modestringlive 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
livetestdisabled_atstring | nullISO 8601 timestampSet while the subscription is turned off.
created_atstringISO 8601 timestampupdated_atstringISO 8601 timestampsecretstringrequiredHMAC-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 inissueswhen 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). WaitRetry-Afterseconds. 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).
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"
}'{
"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_idstringOnly this project's subscriptions.
Returns
200 OK
Response attributes
dataarray of WebhookSubscriptionrequired9 attributes
idstringrequiredorg_idstringrequiredproject_idstringrequiredurlstringrequireduriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringrequiredSubscribed event types; empty = all.
modestringlive 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
livetestdisabled_atstring | nullISO 8601 timestampSet while the subscription is turned off.
created_atstringISO 8601 timestampupdated_atstringISO 8601 timestamp
- 401 Missing, malformed, unknown or revoked API key (
unauthorized) - 429 Rate limit exceeded (
rate_limited). WaitRetry-Afterseconds. 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).
curl "https://api.myleadsfactory.tech/api/webhooks" \
-H "Authorization: Bearer $MLF_API_KEY"{
"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
idstringrequiredSubscription id,
whsub_....
Returns
200 OK
Response attributes
dataWebhookSubscriptionrequired9 attributes
idstringrequiredorg_idstringrequiredproject_idstringrequiredurlstringrequireduriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringrequiredSubscribed event types; empty = all.
modestringlive 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
livetestdisabled_atstring | nullISO 8601 timestampSet while the subscription is turned off.
created_atstringISO 8601 timestampupdated_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). WaitRetry-Afterseconds. 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).
curl "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID" \
-H "Authorization: Bearer $MLF_API_KEY"{
"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
idstringrequiredSubscription id,
whsub_....
Request body
urlstringuriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringReplaces the event list; empty means all. An unknown name is refused with 400.
secretstringnot emptyA new signing secret. Write-only.
enabledbooleanFalse turns deliveries off; true turns them back on.
modestringAccepted only when it is the subscription's current mode, so a read can be sent back; a change is refused.
One of
livetest
Returns
200 OK
Response attributes
dataWebhookSubscriptionrequired9 attributes
idstringrequiredorg_idstringrequiredproject_idstringrequiredurlstringrequireduriPublic HTTPS destination. Private addresses and redirects are refused at delivery.
eventsarray of stringrequiredSubscribed event types; empty = all.
modestringlive 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
livetestdisabled_atstring | nullISO 8601 timestampSet while the subscription is turned off.
created_atstringISO 8601 timestampupdated_atstringISO 8601 timestamp
- 400 Validation error: usually
invalid_request, with the failing fields inissueswhen 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). WaitRetry-Afterseconds. 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).
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
}'{
"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
idstringrequiredSubscription id,
whsub_....
Returns
200 OK
Response attributes
dataDeleteResultrequired2 attributes
idstringrequireddeletedbooleanrequired
- 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). WaitRetry-Afterseconds. 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).
curl -X DELETE "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID" \
-H "Authorization: Bearer $MLF_API_KEY"{
"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
idstringrequiredSubscription id,
whsub_....
Query parameters
statusstringOnly deliveries in this state.
One of
pendingdeliveredfailed
Returns
200 OK
Response attributes
dataarray of WebhookDeliveryrequired13 attributes
idstringrequiredevent_idstringrequiredsubscription_idstringrequiredproject_idstringeventstringrequiredstatusstringrequiredOne of
pendingdeliveredfailedattemptsintegerrequiredlast_statusinteger | nullHTTP status of the latest attempt.
last_errorstring | nulllast_attempt_atstring | nullISO 8601 timestampdelivered_atstring | nullISO 8601 timestampcreated_atstringrequiredISO 8601 timestampupdated_atstringISO 8601 timestamp
- 400 Validation error: usually
invalid_request, with the failing fields inissueswhen 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). WaitRetry-Afterseconds. 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).
curl "https://api.myleadsfactory.tech/api/webhooks/WEBHOOK_ID/deliveries" \
-H "Authorization: Bearer $MLF_API_KEY"{
"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"
}
]
}