Webhook Subscriptions
A webhook subscription names one owner — a mailbox or a phone number — one HTTPS destination URL, and a non-empty list of event types from the webhook catalog. When a matching event fires, Inkbox POSTs the payload to the subscription's URL.
You can attach up to 20 active subscriptions per owner (mailbox or phone number). Each URL receives its own POST per event, independently — one slow receiver doesn't block delivery to the others. A 21st POST /webhooks/subscriptions on the same owner returns 409; delete an existing subscription first.
phone.incoming_callis not subscribable. That event is a synchronous control-plane callback — the response body decides whether Inkbox answers the call — so it can't fan out. Configure it via theincoming_call_webhook_urlfield on the phone number resource instead.
Auth
| Caller | Visibility |
|---|---|
| Admin-scoped API key | Every subscription in the organization. |
| Human session via the Inkbox Console | Every subscription in the organization. |
| Claimed agent-scoped API key | Only subscriptions whose owning mailbox or phone number belongs to that agent's identity. |
Unclaimed agent-scoped API keys are rejected.
Create subscription POST
POST /webhooks/subscriptionsCreate a new subscription on a mailbox or a phone number.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
mailbox_id | UUID | Conditionally | Owning mailbox. Exactly one of mailbox_id / phone_number_id must be set. |
phone_number_id | UUID | Conditionally | Owning phone number. Exactly one of mailbox_id / phone_number_id must be set. |
url | string | Yes | HTTPS destination for delivered events. |
event_types | array of strings | Yes | Non-empty, distinct list of event types. Every entry must belong to the owner's channel (mailbox_id → message.*; phone_number_id → text.*). |
Request example
Response (201)
Returns the new subscription object. See Subscription object.
Validation errors
| Status | Reason |
|---|---|
422 | Body specified neither or both of mailbox_id / phone_number_id. |
422 | event_types was empty or contained duplicates. |
422 | An event type doesn't belong to the owner's channel (e.g. text.received on a mailbox_id). |
422 | phone.incoming_call was included — managed via the phone-number resource instead. |
403 | mailbox_id belongs to a different organization than the caller. |
404 | mailbox_id or phone_number_id is not visible to the caller (does not exist, or hidden by access scope). |
409 | An active subscription with the same (owner, url) pair already exists. |
Code examples
List subscriptions GET
GET /webhooks/subscriptionsList active subscriptions visible to the caller, newest first. Returns an object with a subscriptions array — not a bare array.
Query parameters
| Parameter | Type | Description |
|---|---|---|
mailbox_id | UUID | Filter by owning mailbox. Mutually exclusive with phone_number_id. |
phone_number_id | UUID | Filter by owning phone number. Mutually exclusive with mailbox_id. |
url | string | Filter by exact destination URL. |
event_type | string | Filter by event type. phone.incoming_call is rejected — that event isn't stored as a subscription. |
Filters AND-combine. Foreign-organization rows are filtered out, so they never appear in results.
Response (200)
Error responses
| Status | Reason |
|---|---|
422 | Both mailbox_id and phone_number_id supplied. |
422 | event_type=phone.incoming_call. |
Code examples
Get subscription GET
GET /webhooks/subscriptions/{sub_id}Path parameters
| Parameter | Type | Description |
|---|---|---|
sub_id | UUID | Unique subscription identifier. |
Response (200)
Returns the subscription object. See Subscription object.
Error responses
| Status | Reason |
|---|---|
404 | Subscription does not exist or is not visible to the caller. Foreign-organization subscriptions return 404. |
Code examples
Update subscription PATCH
PATCH /webhooks/subscriptions/{sub_id}Update a subscription's destination URL and/or event list in place. The owner FKs are immutable — to move a subscription to a different mailbox or phone number, delete it and create a new one.
Path parameters
| Parameter | Type | Description |
|---|---|---|
sub_id | UUID | Unique subscription identifier. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | New HTTPS destination. Omit to leave unchanged. |
event_types | array of strings | No | New non-empty, distinct list of event types. Same channel-coherence rules as create. Omit to leave unchanged. |
Supplying both fields is fine. Supplying neither no-ops.
Request example
Response (200)
Returns the updated subscription object. See Subscription object.
Validation errors
| Status | Reason |
|---|---|
422 | event_types was empty or contained duplicates. |
422 | An event type doesn't belong to the owner's channel. |
422 | phone.incoming_call was included. |
404 | Subscription does not exist or is not visible to the caller. |
409 | The new (owner, url) collides with another active subscription. |
Code examples
Delete subscription DELETE
DELETE /webhooks/subscriptions/{sub_id}Remove a subscription. Inkbox stops delivering events to the URL immediately. Subsequent reads on the same sub_id return 404.
Path parameters
| Parameter | Type | Description |
|---|---|---|
sub_id | UUID | Unique subscription identifier. |
Response (204)
No body.
Error responses
| Status | Reason |
|---|---|
404 | Subscription does not exist or is not visible to the caller. |
Code examples
Subscription object
| Field | Type | Description |
|---|---|---|
id | UUID | Unique subscription identifier. |
organization_id | string | Owning organization (e.g. "org_2abc123def456"). Server-derived from the owner — never read from the request body. |
mailbox_id | UUID | null | Owning mailbox. Populated when this is a mail subscription; null otherwise. |
phone_number_id | UUID | null | Owning phone number. Populated when this is a text subscription; null otherwise. |
url | string | HTTPS destination for delivered events. |
event_types | array of strings | Event types this subscription delivers. Every value belongs to the owner's channel. |
status | string | Always "active" on returned rows. Deleted rows are not returned by any endpoint. |
created_at | string | ISO 8601 timestamp the subscription was created. |
updated_at | string | ISO 8601 timestamp the subscription was last updated. |
Event types
event_types is a non-empty list drawn from the same catalog the webhook payload pages document:
| Channel | Allowed values |
|---|---|
Mail (mailbox_id owner) | message.received, message.sent, message.forwarded, message.delivered, message.bounced, message.failed |
Phone text (phone_number_id owner) | text.received, text.sent, text.delivered, text.delivery_failed, text.delivery_unconfirmed |
phone.incoming_call is not in this list. It is managed via incoming_call_webhook_url on the phone number resource.
- Webhooks guide — payload verification, typed receiver examples
- Mail webhooks reference —
message.*payload shapes - Phone webhooks reference —
text.*andphone.incoming_callpayload shapes - Signing keys — rotate the org-level HMAC key used to sign webhook bodies