Skip to content

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}.

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.
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.
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.

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.

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.