Skip to main content

Messages

Every call needs Authorization: Bearer <key>. 8 calls:

Check whether a number is on iMessage​

POST /v1/lookup

Cached for 30 days per workspace. Pass refresh: true to check again. Test keys and test numbers are answered by the simulator.

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.
idempotency-keystringNoMakes 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

FieldTypeRequiredDescription
phonestringYesPhone number in E.164 format.
refreshbooleanNoIgnore the 30-day cache. Default false.

Response 200

FieldTypeDescription
cachedboolean
checked_atstring (date-time)ISO 8601 timestamp.
imessageboolean
phonestringPhone number in E.164 format.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

List messages​

GET /v1/messages

Newest first. Agents see messages in conversations they can see; service identities see messages on their lines and messages they sent.

Query parameters

NameTypeRequiredDescription
limitintegerNoFrom 1 to 100. Default 50.
cursorstringNoOpaque cursor from next_cursor. Up to 512 characters.
statusenumNoOne of: queued, scheduled, sending, sent, delivered, read, failed, received.
directionenumNoOne of: outbound, inbound.
channelenumNoOne of: imessage, sms.
contact_idstringNoContact id (ctc_...).
conversation_idstringNoConversation id (cnv_...).
line_idstringNoLine id (ln_...).
external_idstringNoUp to 255 characters.
created_afterstring (date-time)NoISO 8601 timestamp.
created_beforestring (date-time)NoISO 8601 timestamp.

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.

Response 200

FieldTypeDescription
dataobject[]
data[].bodystring
data[].channelenumOne of: imessage, sms.
data[].contact_idstringContact id (ctc_...).
data[].conversation_idstringConversation id (cnv_...).
data[].created_atstring (date-time)ISO 8601 timestamp.
data[].delivered_atstring (date-time) or nullISO 8601 timestamp.
data[].directionenumOne of: outbound, inbound.
data[].error_codestring or null
data[].error_detailsobject or null
data[].external_idstring or null
data[].fromstring or nullPhone number in E.164 format.
data[].idstringMessage id (msg_...).
data[].is_testboolean
data[].line_idstring or nullLine id (ln_...).
data[].mediaobject[]
data[].media[].filenamestring or null
data[].media[].mimestring or null
data[].media[].sizeinteger or nullFrom 0 to 9007199254740991.
data[].media[].urlstring
data[].metadataobject
data[].read_atstring (date-time) or nullISO 8601 timestamp.
data[].scheduled_forstring (date-time) or nullISO 8601 timestamp.
data[].sent_atstring (date-time) or nullISO 8601 timestamp.
data[].sent_by_staffboolean
data[].sourceenum or nullOne of: api, dashboard, workflow, agent, outreach, mcp.
data[].statusenumOne of: queued, scheduled, sending, sent, delivered, read, failed, received.
data[].tostring or nullPhone number in E.164 format.
data[].updated_atstring (date-time)ISO 8601 timestamp.
next_cursorstring or nullPass 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.

Send a message​

POST /v1/messages

Queues the message and returns it. The worker routes, governs, paces and sends it; follow progress with GET /v1/messages/:id or the message.status webhook.

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.
idempotency-keystringNoMakes 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

FieldTypeRequiredDescription
bodystringNoUp to 2000 characters.
contact_idstringNoContact id (ctc_...).
external_idstringNoUp to 255 characters.
fallbackbooleanNoSet false to forbid SMS fallback; otherwise the pool's fallback_sms_mode decides.
line_idstringNoLine id (ln_...).
mediaobject[]NoUp to 10 items.
media[].filenamestringNoUp to 255 characters.
media[].mimestringNoUp to 100 characters.
media[].urlstring (uri)YesPublicly fetchable URL of the file. Up to 2048 characters.
metadataobjectNoUp to 50 key/value pairs.
pool_idstringNoPool id (pool_...).
send_atstring (date-time)NoSchedule for later, at most one year ahead; the governor may still defer it.
tostringNoRecipient phone number. Provide to or contact_id.

Response 201

FieldTypeDescription
bodystring
channelenumOne of: imessage, sms.
contact_idstringContact id (ctc_...).
conversation_idstringConversation id (cnv_...).
created_atstring (date-time)ISO 8601 timestamp.
delivered_atstring (date-time) or nullISO 8601 timestamp.
directionenumOne of: outbound, inbound.
error_codestring or null
error_detailsobject or null
external_idstring or null
fromstring or nullPhone number in E.164 format.
idstringMessage id (msg_...).
is_testboolean
line_idstring or nullLine id (ln_...).
mediaobject[]
media[].filenamestring or null
media[].mimestring or null
media[].sizeinteger or nullFrom 0 to 9007199254740991.
media[].urlstring
metadataobject
read_atstring (date-time) or nullISO 8601 timestamp.
scheduled_forstring (date-time) or nullISO 8601 timestamp.
sent_atstring (date-time) or nullISO 8601 timestamp.
sent_by_staffboolean
sourceenum or nullOne of: api, dashboard, workflow, agent, outreach, mcp.
statusenumOne of: queued, scheduled, sending, sent, delivered, read, failed, received.
tostring or nullPhone number in E.164 format.
updated_atstring (date-time)ISO 8601 timestamp.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

Check a message before sending it​

POST /v1/messages/check

Takes the same body as POST /v1/messages and returns what the governor would decide: allow, defer (with until and the reason) or reject (with the code and the reason), and how many new contacts the line can still text today and this hour. Nothing is sent, queued, counted or stored, and no option skips a rule. An Idempotency-Key is ignored, so the same key still works for the send. With send_at, the text is checked as of that time (quiet hours and content); the line’s caps are predicted only for a send now. A contact bubbl3 knows isn’t on iMessage is checked under the SMS rules (consent, content and quiet hours, and whether the pool can fall back to SMS). Anyone else is checked as on iMessage, and if they turn out not to be, the SMS rules decide at send time: a text that would be deferred or refused by the line’s caps or limits here may then go out by SMS straight away. Rate-limited like other reads.

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.

Request body

FieldTypeRequiredDescription
bodystringNoUp to 2000 characters.
contact_idstringNoContact id (ctc_...).
external_idstringNoUp to 255 characters.
fallbackbooleanNoSet false to forbid SMS fallback; otherwise the pool's fallback_sms_mode decides.
line_idstringNoLine id (ln_...).
mediaobject[]NoUp to 10 items.
media[].filenamestringNoUp to 255 characters.
media[].mimestringNoUp to 100 characters.
media[].urlstring (uri)YesPublicly fetchable URL of the file. Up to 2048 characters.
metadataobjectNoUp to 50 key/value pairs.
pool_idstringNoPool id (pool_...).
send_atstring (date-time)NoSchedule for later, at most one year ahead; the governor may still defer it.
tostringNoRecipient phone number. Provide to or contact_id.

Response 200

FieldTypeDescription
lineobject or nullThe line that would send it, and how many new contacts it can still text.
line.idstringLine id (ln_...).
line.new_contacts_left_this_hourintegerFrom 0 to 9007199254740991.
line.new_contacts_left_todayintegerFrom 0 to 9007199254740991.
recipientsobject[]
recipients[].codestring or nullFor reject, the error code the message would fail with; for defer, the reason.
recipients[].contact_idstring or nullThe existing contact, if there is one.
recipients[].decisionenumWhat a send now would get: allow (queued to send), defer (queued until until) or reject. One of: allow, defer, reject.
recipients[].line_idstring or nullThe line that would send it.
recipients[].reasonstring or nullThe decision in plain words, for people.
recipients[].tostring or nullThe recipient’s number, when the request named one.
recipients[].untilstring (date-time) or nullFor defer, when the message would go out.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

Get a message and its status​

GET /v1/messages/:id

Path parameters

NameTypeRequiredDescription
idstringYesMessage id (msg_...).

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.

Response 200

FieldTypeDescription
bodystring
channelenumOne of: imessage, sms.
contact_idstringContact id (ctc_...).
conversation_idstringConversation id (cnv_...).
created_atstring (date-time)ISO 8601 timestamp.
delivered_atstring (date-time) or nullISO 8601 timestamp.
directionenumOne of: outbound, inbound.
error_codestring or null
error_detailsobject or null
external_idstring or null
fromstring or nullPhone number in E.164 format.
idstringMessage id (msg_...).
is_testboolean
line_idstring or nullLine id (ln_...).
mediaobject[]
media[].filenamestring or null
media[].mimestring or null
media[].sizeinteger or nullFrom 0 to 9007199254740991.
media[].urlstring
metadataobject
read_atstring (date-time) or nullISO 8601 timestamp.
scheduled_forstring (date-time) or nullISO 8601 timestamp.
sent_atstring (date-time) or nullISO 8601 timestamp.
sent_by_staffboolean
sourceenum or nullOne of: api, dashboard, workflow, agent, outreach, mcp.
statusenumOne of: queued, scheduled, sending, sent, delivered, read, failed, received.
tostring or nullPhone number in E.164 format.
updated_atstring (date-time)ISO 8601 timestamp.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

Get a message’s delivery timeline​

GET /v1/messages/:id/events

Oldest first: accepted, routed, deferred, sent, delivered, read and so on.

Path parameters

NameTypeRequiredDescription
idstringYesMessage id (msg_...).

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.

Response 200

FieldTypeDescription
dataobject[]
data[].detailobjectEvent-specific detail, e.g. the deferral reason. On receipt_missing, unverified: true means the device could not be asked, so the receipt is not known to be missing and does not count against the line.
data[].idstring (uuid)
data[].occurred_atstring (date-time)ISO 8601 timestamp.
data[].typeenumOne of: accepted, routed, capability_checked, deferred, rejected, sending, sent, delivered, read, failed, retried, fallback_sms, received, receipt_missing, send_unconfirmed.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

Sandbox state​

GET /v1/sandbox

The organisation's sandbox setting and the workspace's sandbox lines. A sandbox line is created by the first sandboxed message, so the list starts empty.

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.

Response 200

FieldTypeDescription
enabledbooleanThe organisation's sandbox setting.
linesobject[]The workspace’s sandbox lines. Empty until the first sandboxed message.
lines[].contact_cardobject
lines[].contact_card.image_urlstringUp to 2048 characters.
lines[].contact_card.namestringUp to 100 characters.
lines[].created_atstring (date-time)ISO 8601 timestamp.
lines[].daily_new_capintegerFrom 0 to 9007199254740991.
lines[].display_namestring or null
lines[].health_scoreintegerFrom 0 to 100.
lines[].idstringLine id (ln_...).
lines[].is_sandboxboolean
lines[].phonestringPhone number in E.164 format.
lines[].pool_idstring or nullPool id (pool_...).
lines[].stateenumOne of: provisioning, ready, warming, active, throttled, paused, quarantined, retired.
lines[].state_changed_atstring (date-time) or nullISO 8601 timestamp.
lines[].state_reasonstring or null
lines[].usage_todayobject
lines[].usage_today.daystring (date)Usage day in America/New_York, rolling over at 3 AM.
lines[].usage_today.new_contactsintegerFrom 0 to 9007199254740991.
lines[].usage_today.new_contacts_capintegerFrom 0 to 9007199254740991.
lines[].usage_today.sendsintegerFrom 0 to 9007199254740991.
lines[].usage_today.sends_capintegerFrom 0 to 9007199254740991.
lines[].warmup_dayintegerFrom 0 to 9007199254740991.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.

Simulate an inbound reply (sandbox only)​

POST /v1/sandbox/inbound

Records a text from a test number (+1 NPA 555 01xx) to a sandbox line, as if the contact had replied: the contact is matched or created, the conversation opens and message.received fires. STOP and START keywords apply. Without line_id the workspace’s sandbox line is used (created on first use).

Headers

NameTypeRequiredDescription
x-workspace-idstringNoWorkspace for session (JWT) callers. API keys carry their own workspace.
idempotency-keystringNoMakes 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

FieldTypeRequiredDescription
bodystringYesUp to 2000 characters.
fromstringYesSender. Sandbox only accepts test numbers.
line_idstringNoA sandbox line in the workspace. Defaults to the workspace’s sandbox line.
mediaobject[]NoUp to 10 items.
media[].filenamestringNoUp to 255 characters.
media[].mimestringNoUp to 100 characters.
media[].urlstring (uri)YesPublicly fetchable URL of the file. Up to 2048 characters.

Response 201

FieldTypeDescription
bodystring
channelenumOne of: imessage, sms.
contact_idstringContact id (ctc_...).
conversation_idstringConversation id (cnv_...).
created_atstring (date-time)ISO 8601 timestamp.
delivered_atstring (date-time) or nullISO 8601 timestamp.
directionenumOne of: outbound, inbound.
error_codestring or null
error_detailsobject or null
external_idstring or null
fromstring or nullPhone number in E.164 format.
idstringMessage id (msg_...).
is_testboolean
line_idstring or nullLine id (ln_...).
mediaobject[]
media[].filenamestring or null
media[].mimestring or null
media[].sizeinteger or nullFrom 0 to 9007199254740991.
media[].urlstring
metadataobject
read_atstring (date-time) or nullISO 8601 timestamp.
scheduled_forstring (date-time) or nullISO 8601 timestamp.
sent_atstring (date-time) or nullISO 8601 timestamp.
sent_by_staffboolean
sourceenum or nullOne of: api, dashboard, workflow, agent, outreach, mcp.
statusenumOne of: queued, scheduled, sending, sent, delivered, read, failed, received.
tostring or nullPhone number in E.164 format.
updated_atstring (date-time)ISO 8601 timestamp.

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500. See errors for the shape and codes.