Skip to main content
A threaded reply answers one specific message, and the recipient sees it in that message’s iMessage thread. You send one by adding 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

Add reply_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

When Blujay chooses the service (Auto) and a direct reply can only go out as SMS or RCS, the message isn’t sent. It moves to 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, from GET /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)
  • order is asc (oldest first, the default) or desc.
  • limit defaults to 25 and goes up to 100. When has_more is true, pass next_cursor as cursor with the same order.
  • One thread read covers at most 1,000 messages of the thread, counted from its start with order=asc or from its end with order=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_history to get earlier versions of edited messages. See Edit and unsend.

Get reply details in webhooks

Subscriptions on webhook version 2026-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.
Common mistakes
  • A reply is a follow-up. reply_to on POST /v1/chats returns 400 VALIDATION_ERROR.
  • 404 REPLY_TARGET_NOT_FOUND for an ID you know exists usually means the target was sent or received on a different phone number than the chat.
  • The pre-reply rules still apply: a reply with a link or media before the contact has replied returns 400 PRE_REPLY_CONTENT_BLOCKED. See Sending rules.
  • A reply that can’t go out over iMessage fails. It’s never sent as a plain SMS.

Limitations

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.