conversation_id; callers never choose a sending number in the message request. Shared lines remain hidden, while an attached dedicated line lets the identity start a conversation or group.
Send message
conversation_id to reply into an existing conversation, or to as either one E.164 phone number or a list of 1-8 E.164 phone numbers — exactly one of the two.
Shared-service identities can reply only after the recipient has started a conversation. A dedicated line can start a new 1:1 conversation or a group chat; lists with 2-8 recipients select group behavior, while a scalar or one-item list keeps the 1:1 behavior.
Reply into a conversation:
JSON
JSON
JSON
409. A different to set never edits an existing group’s membership. Keep the returned conversation_id and use it to continue the exact same thread. See Group chats for membership and delivery semantics.
Query parameters
Request body
Preconditions
- Identity opt-in. The sending identity must have
imessage_enabled: true; otherwise sends return400. - Line capability. Shared service requires recipient-first contact. A dedicated line can start 1:1 conversations and is required for groups.
- Group participants. Group
tolists contain 2-8 distinct remote E.164 phone numbers and cannot include the attached sending line. Every participant must pass opt-out and contact-rule checks before the message is queued. - Connection still active. If the recipient disconnected from the agent, sends into the old conversation return
409until they reconnect through the router. - Contact rules. Sends to a recipient blocked by the identity’s contact rules return
403before anything is sent.
Rate limits
Each agent identity can send up to 100 iMessages per rolling 24-hour window. When the cap is reached,429 responses include:
Dedicated lines carry additional guardrails on agent-initiated conversations. A dedicated line can start conversations with at most 10 new recipients per rolling 1-hour window and 40 new recipients per rolling 24-hour window, which keeps the line in good standing. Both limits apply only to recipients the line hasn’t reached before:
- It does not apply to a recipient the agent has already connected with on that line.
- It does not apply when the recipient messages the line first.
429 with error: "outbound_line_new_contact_rate_limited" and the same Retry-After and X-RateLimit-* headers. Those headers describe the limit that rejected the request, and Retry-After counts down until enough new-recipient slots in that window age out.
Response (201)
The queued message, wrapped in amessage envelope. Delivery state updates asynchronously — re-read the message, or subscribe to the delivery-lifecycle webhooks (imessage.sent, imessage.delivered, imessage.delivery_failed) to track it without polling.
JSON
Error responses
The
404 and 409 connection errors carry a structured detail — read detail.error to branch and detail.message for the sentence to relay:
Reactions, read receipts, and typing indicators return
imessage_assignment_inactive the same way when the conversation’s assignment is no longer active.
Delivery happens asynchronously after the 201, so delivery failures never surface as send-request errors. Re-read the message to observe every outcome; delivery-lifecycle transitions also emit webhooks.
The first message in a new group also creates the group asynchronously. Check the conversation’s group_creation_status: "creating" while that attempt resolves, "ready" after success, or "not_created" after a definitive failure. During creating, the local conversation and pending messages exist before the remote thread does; another send to the same conversation waits behind the elected creation send. A failed first message remains in the same conversation’s history. Send another message using that conversation_id to retry group creation; a successful retry binds that same local conversation for later sends. Existing-group membership is rechecked before delivery, so a change after the 201 can instead move the queued message to status: "error". If you still intend to continue that native thread, a later conversation_id retry resolves its current membership again.
List messages
Query parameters
Identity-scoped API keys never see contact-rule-blocked messages, regardless of
is_blocked. Admin API keys and the Inkbox Console see blocked and non-blocked messages by default; use is_blocked=true for a blocked-only audit listing.
start_datetime, end_datetime, and tz filter on created_at. Both bounds are optional and non-breaking — omit them for unchanged behavior. See Filtering by date.
Response (200)
Returns alist[IMessage]. Live tapbacks ride along on each message — see the Message object.
JSON
Error responses
Upload media
media_urls on a send. The request is multipart/form-data with a single file field.
Request
Response (201)
JSON
Error responses
Send styles
Passsend_style on a 1:1 or group send to apply one of Apple’s expressive effects. Dedicated-line groups support styles on both creation and conversation_id replies, including messages that also carry the single allowed media item:
Send styles render on the recipient’s device when the message is delivered over iMessage; they do not apply to SMS fallback.

