Webhooks
Every call needs Authorization: Bearer <key>. 8 calls:
- Replay a delivery:
POST /v1/webhook-deliveries/:id/replay - List webhook endpoints:
GET /v1/webhooks - Create a webhook endpoint:
POST /v1/webhooks - Update a webhook endpoint:
PATCH /v1/webhooks/:id - Delete a webhook endpoint:
DELETE /v1/webhooks/:id - List an endpoint's deliveries:
GET /v1/webhooks/:id/deliveries - Rotate a webhook signing secret:
POST /v1/webhooks/:id/rotate - Send a test event:
POST /v1/webhooks/:id/test
Replay a delivery
POST /v1/webhook-deliveries/:id/replay
Sends the same event again (same event id, fresh signature) as one new attempt. The delivery must be finished (succeeded or failed) and its endpoint active. At most 30 a minute per workspace.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 202
| Field | Type | Description |
|---|---|---|
attempt | integer | Attempts made so far; 0 until the first one runs. From 0 to 9007199254740991. |
created_at | string (date-time) | ISO 8601 timestamp. |
delivered_at | string (date-time) or null | ISO 8601 timestamp. |
endpoint_id | string | Webhook endpoint id (whk_...). |
error | string or null | |
event_id | string | Event id (evt_...). |
event_type | enum | One of: message.received, message.status, contact.created, contact.opted_out, contact.opted_in, conversation.assigned, line.state_changed, line.degraded, line.recovered, workflow.run.completed, agent.handoff, workflow.webhook. |
id | string (uuid) | |
latency_ms | integer or null | From 0 to 9007199254740991. |
next_attempt_at | string (date-time) or null | ISO 8601 timestamp. |
status | enum | One of: pending, succeeded, failed. |
status_code | integer or null | From -9007199254740991 to 9007199254740991. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List webhook endpoints
GET /v1/webhooks
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].disabled_at | string (date-time) or null | ISO 8601 timestamp. |
data[].disabled_reason | string or null | |
data[].events | enum[] | |
data[].failure_rate_7d | number | Fraction from 0 to 1. From 0 to 1. |
data[].id | string | Webhook endpoint id (whk_...). |
data[].status | enum | One of: active, paused, disabled. |
data[].updated_at | string (date-time) | ISO 8601 timestamp. |
data[].url | string | |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Create a webhook endpoint
POST /v1/webhooks
The signing secret is returned once, in secret. It is stored encrypted and never shown again; rotate it to get a new one. A workspace can have up to 20 endpoints, and an organization up to 50.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
events | enum[] | Yes | |
url | string (uri) | Yes | HTTPS URL. Up to 2048 characters. |
Response 201
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
disabled_at | string (date-time) or null | ISO 8601 timestamp. |
disabled_reason | string or null | |
events | enum[] | |
failure_rate_7d | number | Fraction from 0 to 1. From 0 to 1. |
id | string | Webhook endpoint id (whk_...). |
secret | string | Signing secret. Shown once. |
status | enum | One of: active, paused, disabled. |
updated_at | string (date-time) | ISO 8601 timestamp. |
url | string |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Update a webhook endpoint
PATCH /v1/webhooks/:id
Change the URL or events, pause it, or set active to resume a paused endpoint or re-enable a disabled one. Re-enabling starts a fresh failure window, and a disabled endpoint can be re-enabled at most once every 10 minutes. A disabled endpoint can't be paused; re-enable it first.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook endpoint id (whk_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
events | enum[] | No | |
status | enum | No | One of: active, paused. |
url | string (uri) | No | HTTPS URL. Up to 2048 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
disabled_at | string (date-time) or null | ISO 8601 timestamp. |
disabled_reason | string or null | |
events | enum[] | |
failure_rate_7d | number | Fraction from 0 to 1. From 0 to 1. |
id | string | Webhook endpoint id (whk_...). |
status | enum | One of: active, paused, disabled. |
updated_at | string (date-time) | ISO 8601 timestamp. |
url | string |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Delete a webhook endpoint
DELETE /v1/webhooks/:id
Deliveries stop at once. The endpoint and its delivery history are removed.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook endpoint id (whk_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
deleted | enum | One of: true. |
id | string | Webhook endpoint id (whk_...). |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
List an endpoint's deliveries
GET /v1/webhooks/:id/deliveries
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook endpoint id (whk_...). |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | No | From 1 to 100. Default 50. |
cursor | string | No | Opaque cursor from next_cursor. Up to 512 characters. |
status | enum | No | One of: pending, succeeded, failed. |
event_type | enum | No | One of: message.received, message.status, contact.created, contact.opted_out, contact.opted_in, conversation.assigned, line.state_changed, line.degraded, line.recovered, workflow.run.completed, agent.handoff, workflow.webhook. |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
Response 200
| Field | Type | Description |
|---|---|---|
data | object[] | |
data[].attempt | integer | Attempts made so far; 0 until the first one runs. From 0 to 9007199254740991. |
data[].created_at | string (date-time) | ISO 8601 timestamp. |
data[].delivered_at | string (date-time) or null | ISO 8601 timestamp. |
data[].endpoint_id | string | Webhook endpoint id (whk_...). |
data[].error | string or null | |
data[].event_id | string | Event id (evt_...). |
data[].event_type | enum | One of: message.received, message.status, contact.created, contact.opted_out, contact.opted_in, conversation.assigned, line.state_changed, line.degraded, line.recovered, workflow.run.completed, agent.handoff, workflow.webhook. |
data[].id | string (uuid) | |
data[].latency_ms | integer or null | From 0 to 9007199254740991. |
data[].next_attempt_at | string (date-time) or null | ISO 8601 timestamp. |
data[].status | enum | One of: pending, succeeded, failed. |
data[].status_code | integer or null | From -9007199254740991 to 9007199254740991. |
next_cursor | string or null | Pass as cursor to get the next page; null at the end. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Rotate a webhook signing secret
POST /v1/webhooks/:id/rotate
Returns a new secret once. For 24 hours each delivery carries two v1 signatures, one per secret, so receivers can switch over without dropping events.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook endpoint id (whk_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Response 200
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | ISO 8601 timestamp. |
disabled_at | string (date-time) or null | ISO 8601 timestamp. |
disabled_reason | string or null | |
events | enum[] | |
failure_rate_7d | number | Fraction from 0 to 1. From 0 to 1. |
id | string | Webhook endpoint id (whk_...). |
secret | string | Signing secret. Shown once. |
status | enum | One of: active, paused, disabled. |
updated_at | string (date-time) | ISO 8601 timestamp. |
url | string |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.
Send a test event
POST /v1/webhooks/:id/test
Queues one signed delivery of an example event (fixed placeholder data, is_test where the shape has it). Test events are attempted once and never count toward auto-disable. At most 10 a minute per workspace.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Webhook endpoint id (whk_...). |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
x-workspace-id | string | No | Workspace for session (JWT) callers. API keys carry their own workspace. |
idempotency-key | string | No | Makes the write safe to retry for 24 hours. 1 to 255 printable characters. Keys starting with outreach:, workflow: or agent: are reserved for messages bubbl3 sends itself and are refused with 400. Up to 255 characters. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
type | enum | No | One of: message.received, message.status, contact.created, contact.opted_out, contact.opted_in, conversation.assigned, line.state_changed, line.degraded, line.recovered, workflow.run.completed, agent.handoff, workflow.webhook. Default "message.received". |
Response 202
| Field | Type | Description |
|---|---|---|
attempt | integer | Attempts made so far; 0 until the first one runs. From 0 to 9007199254740991. |
created_at | string (date-time) | ISO 8601 timestamp. |
delivered_at | string (date-time) or null | ISO 8601 timestamp. |
endpoint_id | string | Webhook endpoint id (whk_...). |
error | string or null | |
event_id | string | Event id (evt_...). |
event_type | enum | One of: message.received, message.status, contact.created, contact.opted_out, contact.opted_in, conversation.assigned, line.state_changed, line.degraded, line.recovered, workflow.run.completed, agent.handoff, workflow.webhook. |
id | string (uuid) | |
latency_ms | integer or null | From 0 to 9007199254740991. |
next_attempt_at | string (date-time) or null | ISO 8601 timestamp. |
status | enum | One of: pending, succeeded, failed. |
status_code | integer or null | From -9007199254740991 to 9007199254740991. |
Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.