Skip to content
Miss Blue

Reference

Messages

Sending is the whole point. A send is accepted here and leaves the Mac shortly after — see queued below, and Delivery for how you find out what happened to it.

Send an iMessage.

Text, files, or a reply quoting an earlier message. Sending to an existing group is the same call with the group's chat_id as the recipient.

number_id*uuidWhich of your numbers to send from. GET /v1/numbers lists them.
recipient*stringA phone number, an Apple ID email, or a chat_id to send into an existing conversation.
textstringOptional only if you are sending attachments — a message must carry one or the other.
attachment_idsuuid[]From POST /v1/attachments. iMessage has no captions, so text and attachments are sent as separate messages.
reply_to_message_iduuidOur id for the message being quoted, not Apple's.
status_callbackhttps urlWhere to POST this one message's outcome. See Delivery.
allow_duplicatebooleanSend anyway, though the same text went to the same person moments ago.
curl -X POST https://api.missblue.dev/v1/messages \
  -H "Authorization: Bearer $MISS_BLUE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "number_id": "8f14e45f-ceea-467a-9a1b-1b1e5f9e2c3d",
    "recipient": "+15555550100",
    "text": "Your table is confirmed for 7pm."
  }'

Response

{
  "id": "0b5ed7e8-f7a1-4f6e-9c2a-2a1f0d9e8b77",
  "status": "sent",
  "queued": false,
  "chat_id": "iMessage;-;+15555550100"
}
  • 400No text and no attachments, or neither number_id nor agent_id.
  • 404A number_id your key does not hold. Not 403 — whether it exists is not your business.
  • 409The same text went to the same person moments ago. Pass allow_duplicate to mean it.
  • 503The Mac holding that number is offline. Retry; nothing was sent.

List messages across your project's numbers, newest first.

curl -X GET https://api.missblue.dev/v1/messages \
  -H "Authorization: Bearer $MISS_BLUE_KEY"

One message, including its current delivery state.

Polling this works, but a webhook or a status_callback tells you sooner and costs you nothing. `agent_version` and `macos_version` say which Mac build handled it, stamped when the message was written rather than looked up now — a Mac that is updated must not rewrite what it was running last week, which is exactly the week you are trying to explain.

curl -X GET https://api.missblue.dev/v1/messages/0b5ed7e8-f7a1-4f6e-9c2a-2a1f0d9e8b77 \
  -H "Authorization: Bearer $MISS_BLUE_KEY"
  • 404No such message, or one on a number your key does not hold.

Every message in one conversation, oldest first.

Ordered by the platform's own sort key, so a message the Mac picked up late still lands where it belongs rather than at the end.

curl -X GET https://api.missblue.dev/v1/messages/thread/iMessage%3B-%3B%2B15555550100 \
  -H "Authorization: Bearer $MISS_BLUE_KEY"

Add or remove a tapback.

reaction_key*stringheart, like, dislike, laugh, emphasize, or question.
removebooleanTake it back rather than add it.
curl -X POST https://api.missblue.dev/v1/messages/0b5ed7e8-f7a1-4f6e-9c2a-2a1f0d9e8b77/react \
  -H "Authorization: Bearer $MISS_BLUE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reaction_key": "heart"
  }'

Messages that failed, or are still waiting for a Mac.

The queue and the failures in one list, because from a caller's side they are the same question: what have I sent that has not arrived. Worth polling on a schedule even if you take webhooks — a webhook that never fired is exactly the case a webhook cannot tell you about.

onlystringqueued or failed. Omit for both.
curl -X GET https://api.missblue.dev/v1/messages/problems \
  -H "Authorization: Bearer $MISS_BLUE_KEY"

Unsend a message.

Apple's two-minute window and its own rules apply. We do not re-check them against our clock — the Mac reports the platform's answer, so a refusal here is Apple's refusal, not ours.

curl -X POST https://api.missblue.dev/v1/messages/0b5ed7e8-f7a1-4f6e-9c2a-2a1f0d9e8b77/unsend \
  -H "Authorization: Bearer $MISS_BLUE_KEY"
NextConversationsThreads, and the typing bubble.