Webhook events
Every delivery has the same envelope; data depends on the type.
{ "id": "evt_0190...", "type": "number.status_changed", "created_at": "2026-10-25T10:00:00.000Z", "data": { } }GET /webhooks/event-types returns the current list with descriptions and the
opt_in flag. In the payloads below, number is the same object as GET /numbers/items/{id}
and account the same as GET /emails/accounts/{email}.
Numbers
Section titled “Numbers”| Event | data |
When |
|---|---|---|
number.rented |
{ number, price } |
You rented a number. |
number.assigned |
{ number } |
A number was assigned to the project, for example a device number was connected. |
number.unassigned |
{ number, reason } |
A number is no longer assigned to the project. |
number.status_changed |
{ number, previous_status, status, status_reason } |
The number’s status changed: it expired, was released, went offline. |
number.metadata_updated |
{ number, previous_version } |
Its metadata changed. |
number.renewal_failed |
{ number, reason, required, balance } |
A monthly number was released, or a device number disconnected, because its renewal could not be paid. reason is insufficient_balance or spend_limit_exceeded; required is the renewal price and balance what the team had. |
number.sms_received |
{ number_id, phone_number, from, to, body, received_at, message_id } |
An SMS arrived on a number. Opt-in. |
Emails
Section titled “Emails”| Event | data |
When |
|---|---|---|
email_account.status_changed |
{ account, previous_status, status, last_error } |
A mailbox’s connection status changed: CONNECTED, RENEWING, REAUTH_REQUIRED or DISCONNECTED. previous_status is null the first time. |
email_account.assigned |
{ account } |
A mailbox was added to the project. |
email_account.unassigned |
{ account, reason } |
A mailbox left the project. reason is disconnected or moved. The account is reduced to id, email, email_provider, metadata and metadata_version. |
email_account.connected |
{ account, auth_link_id, metadata } |
A mailbox finished connecting. When it came from an authorization link, auth_link_id is set; metadata is the mailbox’s metadata with the link’s metadata merged in. |
email_account.metadata_updated |
{ account, previous_version } |
The mailbox’s metadata changed. |
email.received |
{ id, message_id, to, from, subject, received_at, has_attachments, text_preview, account } |
An email arrived. text_preview is the first 500 characters. Opt-in. |
Account
Section titled “Account”| Event | data |
When |
|---|---|---|
balance.low |
{ team_id, balance, threshold, currency } |
The team’s balance dropped below the low balance threshold set in Billing. Sent to every endpoint of the team’s projects that subscribes to it. It fires once and re-arms when the balance is back at or above the threshold. |
Opt-in events
Section titled “Opt-in events”number.sms_received and email.received can be frequent, and an email.received delivery is
charged like any delivered email, so they are never included by *, number.* or
email_account.*. Subscribe to them by their exact name:
{ "event_types": ["number.*", "number.sms_received"] }If the balance or a spend limit cannot cover an email.received delivery, the event is not sent. The email is kept and
you can still read it with GET /emails/wait.
Test events
Section titled “Test events”POST /webhooks/endpoints/{id}/test queues a webhook.test event to that
one endpoint. It has no data of interest; use it to check your URL and your signature verification.