reply_to to a follow-up message. Threaded replies are iMessage only: Blujay never sends a reply without its thread, so a reply that can’t go out as iMessage is refused or fails instead of being sent as a plain message.
Send a reply
Addreply_to to POST /v1/chats/{chat_id}/messages. Set message_id to the message you’re answering.
curl
Response (202)
part_index is optional and defaults to 0. It names which piece of the target message your reply hangs under, using Apple’s numbering for that message. Blujay doesn’t check it against the target’s parts; it passes the number to iMessage as you sent it, and it reports Apple’s number back on replies it receives (the same numbering as part_index in the reaction.added webhook). For a text-only message, 0 is the only part. For a message with media and a caption, Apple’s numbering may not match the order of parts in Blujay, so if a reply lands under the wrong piece, use the other index. Blujay doesn’t publish Apple’s numbering rule.
reply_to works only on follow-ups. POST /v1/chats rejects it with 400 VALIDATION_ERROR, because a chat’s first message can’t be a reply.
Choose a valid target
The target must be a sent iMessage in the same chat, on the same Blujay phone number. Blujay checks the target before it accepts the message, so nothing is sent when one of these errors comes back:Know when a reply can go out
- Direct chats. Leave
preferred_serviceout or set it toiMessage. Setting it toSMSorRCSreturnsUNSUPPORTED_CHAT_OPERATION. - Group chats. The chat must be an established iMessage group. Other groups return
UNSUPPORTED_CHAT_OPERATION. See Group chats.
failed with failure_code: "REPLY_REQUIRES_IMESSAGE". On webhook version 2026-09-02 and later, the message.failed event carries the same failure_code. To reach the person anyway, send the text again without reply_to.
If you retry a reply with the same Idempotency-Key, keep the body identical. Reusing the key with a different reply_to returns 409 IDEMPOTENCY_REQUEST_MISMATCH. A reply Blujay rejected with a 4xx isn’t remembered under its key, so you can fix it and reuse the key. See Idempotency.
Read reply details
Every message you read, fromGET /v1/messages/{message_id}, GET /v1/messages or GET /v1/chats/{chat_id}/messages, has a reply_to field. It is null for a message that isn’t a reply. For a reply, it holds three public IDs:
For a reply you sent through Blujay,
message_id is the message you named. For a reply that arrived over iMessage, Apple reports only the start of the thread, so message_id equals thread_root_message_id. Either ID is null when Blujay doesn’t have that message, for example when it predates your history in Blujay.
Read a whole thread
GET /v1/messages/{message_id}/thread returns the message that started a thread and every reply in it, including replies that are still sending. Pass any message in the thread.
curl
Response (200)
orderisasc(oldest first, the default) ordesc.limitdefaults to 25 and goes up to 100. Whenhas_moreistrue, passnext_cursorascursorwith the sameorder.- One thread read covers at most 1,000 messages of the thread, counted from its start with
order=ascor from its end withorder=desc. Real iMessage threads are far smaller, so you won’t normally hit this. - Reactions are never part of a thread. A message that isn’t in a thread, or a reaction, returns only itself.
- Add
include=edit_historyto get earlier versions of edited messages. See Edit and unsend.
Get reply details in webhooks
Subscriptions on webhook version2026-10-03, the default for new subscriptions, include reply_to on every message event, in the same shape as message reads. Earlier versions never include it. See Webhook versions.
A message.received body is a snapshot taken when the message arrived. If iMessage reports the thread details a moment later, the stored event doesn’t change, so read the message with GET /v1/messages/{message_id} when you need the latest reply_to.
Limitations
- iMessage only.
preferred_service: "SMS"or"RCS"returns400UNSUPPORTED_CHAT_OPERATION; an Auto reply that can only go SMS or RCS fails withREPLY_REQUIRES_IMESSAGE. - The target must be an iMessage in the same chat on the same phone number, sent, not a reaction and not unsent (
404REPLY_TARGET_NOT_FOUND,400REPLY_TARGET_NOT_IN_CHAT,400REPLY_TARGET_NOT_REPLYABLE,409REPLY_TARGET_NOT_SENT). - Groups need an established iMessage group (
400UNSUPPORTED_CHAT_OPERATION). See Group chats. - Not on a first message (
400VALIDATION_ERROR), and subject to the pre-reply rules. part_indexisn’t validated. A wrong index threads under the wrong piece of the message.- For a reply a contact sends,
message_idis the thread root, not the exact message they replied to. - One thread read returns at most 1,000 messages.
Next steps
Send messages
Send follow-ups and track their progress.
Track a message
Understand
failed and failure_code, including REPLY_REQUIRES_IMESSAGE.Group chats
See which group features need an established iMessage group.
Webhook versions
Move to
2026-10-03 to get reply_to in message events.