Skip to content
Inkbox

Inkbox

BlogContactDocs
GuidesAPI Reference

Ctrl K

GuidesAPI Reference

Jump to

Messages

Send and list iMessages. Unlike texts, iMessages are not scoped to a phone number you own — they are scoped to the agent identity and keyed by conversation_id. The pool line carrying a conversation is managed by Inkbox and never appears in responses.


Send message POST

POST /messages

Send an outbound iMessage to a connected recipient. Pass conversation_id to reply into an existing conversation, or to to address the connected recipient by number — exactly one of the two.

Outbound iMessages are replies by design: the recipient must have connected through the router and sent at least one message first. There is no cold outreach over iMessage.

Reply into a conversation:

JSONJSON

Or address the connected recipient directly:

JSONJSON

Query parameters

ParameterTypeDescription
agent_identity_idUUIDThe identity to send as. Required for admin API keys when sending by to; ignored for identity-scoped API keys, which always send as their own identity

Request body

FieldTypeRequiredDescription
tostringConditionalE.164 number of a connected recipient. Mutually exclusive with conversation_id
conversation_idUUIDConditionalExisting conversation to reply into. Mutually exclusive with to
textstring | nullNoMessage body, up to 18,996 characters. Required unless media_urls has an item
media_urlsstring[] | nullNoPublicly fetchable media URL to attach — at most 1 entry. Use Upload media to turn raw bytes into a URL. Required unless text is present
send_stylestring | nullNoExpressive send style applied to the message

Preconditions

  • Identity opt-in. The sending identity must have imessage_enabled: true; otherwise sends return 400.
  • Recipient-first contact. The recipient must be connected to this identity and have sent at least one message. Sending to an unconnected number returns 404; sending into a connection where the recipient hasn't messaged yet returns 409.
  • Connection still active. If the recipient disconnected from the agent, sends into the old conversation return 409 until they reconnect through the router.
  • Contact rules. Sends to a recipient blocked by the identity's contact rules return 403 before 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:

HeaderDescription
X-RateLimit-LimitMaximum sends allowed per identity per 24 hours
X-RateLimit-RemainingRemaining sends in the current window
X-RateLimit-ResetISO 8601 timestamp at which the oldest send in the window will fall off
Retry-AfterSeconds until at least one slot frees up

Response (201)

The queued message, wrapped in a message 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.

JSONJSON

Error responses

StatusDescription
400Sending identity is not enabled for iMessage, or agent_identity_id is missing on an admin send by to
403Recipient is blocked by a contact rule on the identity
404No connection exists for this recipient — the response tells you the connect command and router number to relay
404conversation_id not found
409The recipient hasn't messaged this agent yet, or has disconnected and must reconnect through the router
422Invalid body: both/neither to and conversation_id, no text or media, more than one media_urls entry, or text over 18,996 characters
42924-hour per-identity send limit reached; respect the Retry-After header

Delivery happens asynchronously after the 201, so provider failures never surface as send errors — they arrive as status: "error" on the message and an imessage.delivery_failed webhook.


List messages GET

GET /messages

List iMessages visible to the caller, newest first, across all of the caller's conversations or narrowed to one.

Query parameters

ParameterTypeDefaultDescription
agent_identity_idUUID-Narrow to one identity. Ignored for identity-scoped API keys, which always see their own identity
conversation_idUUID-Narrow to one conversation
limitinteger50Number of results (1-200)
offsetinteger0Pagination offset
is_readboolean-Filter by read state. Omit for all messages
is_blockedboolean-Filter by blocked state. true returns only blocked rows, false only non-blocked rows, and omitting it applies the caller's default visibility

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.

Response (200)

Returns a list[IMessage]. Live tapbacks ride along on each message — see the Message object.

JSONJSON

Error responses

StatusDescription
400agent_identity_id names an identity that is not enabled for iMessage
403Identity-scoped key passed an agent_identity_id other than its own
404agent_identity_id or conversation_id not found, or not visible to the caller

Upload media POST

POST /media

Upload a file and get back a URL you can pass in media_urls on a send. The request is multipart/form-data with a single file field.

Request

FieldTypeRequiredDescription
filefileYesThe file to upload, up to 10 MiB. The part's content type and filename are preserved

Response (201)

JSONJSON

Error responses

StatusDescription
400Caller's identity is not enabled for iMessage
413File exceeds 10 MiB
502Upstream upload failure — safe to retry

Send styles

Pass send_style on a send to apply one of Apple's expressive effects:

Bubble effectsFull-screen effects
slamcelebration
loudshooting_star
gentlefireworks
invisible (invisible ink)lasers
love
confetti
balloons
spotlight
echo

Send styles render on the recipient's device when the message is delivered over iMessage; they do not apply to SMS fallback.

Message object

FieldTypeDescription
idstring (UUID)Message ID
conversation_idstring (UUID)The conversation this message belongs to
assignment_idstring (UUID)The connection (one human ↔ one agent) carrying this conversation
directionstring"inbound" or "outbound"
remote_numberstringThe human's phone number (E.164). There is no local-number field — the pool line is managed by Inkbox
contentstring | nullMessage body. Null for media-only messages
message_typestring"message", or "carousel" for rich multi-part messages
servicestringTransport actually used: "imessage", "sms", or "rcs"
send_stylestring | nullSend style applied to the message, if any
mediaarray | nullMedia attachments. Each item has url, content_type, and size. URLs for stored inbound media are presigned and expire after 1 hour
was_downgradedboolean | nullWhether delivery fell back from iMessage to SMS
statusstring | nullDelivery lifecycle: "registered", "pending", "queued", "accepted", "sent", "delivered", "declined", "error", or "received" for inbound
error_codestring | nullDelivery error code, when delivery failed
error_messagestring | nullShort delivery error description
error_reasonstring | nullDelivery error reason, when reported
error_detailstring | nullHuman-readable detail accompanying the error
is_readbooleanRead state. For inbound messages, set by mark-read
is_blockedbooleanWhether the message was blocked by a contact rule or by default-block in whitelist mode. Identity-scoped API keys never receive rows where this is true
recipientsarray | nullPer-recipient delivery state for outbound messages; null for inbound. Each entry has remote_number, delivery_status, service, error fields, and sent_at / delivered_at / failed_at timestamps
reactionsarray | nullLive tapbacks targeting this message, oldest first. Each entry has id, direction, reaction, custom_emoji, remote_number, part_index, and created_at
created_atstring (ISO 8601)Creation timestamp
updated_atstring (ISO 8601)Last update timestamp

Inkbox

Copyright © 2026 Inkbox

This site is protected by reCAPTCHA.

Google Privacy Policy and Terms of Service apply.

Website

Inkbox

Copyright © 2026 Inkbox

This site is protected by reCAPTCHA.

Google Privacy Policy and Terms of Service apply.

Website

Y CombinatorBacked by Y Combinator
Messages