Messagesv4

Get a message

GET/chats/{chatId}/messages/{messageId}

Path parameters

chatIdRequiredstring

Unique identifier of the chat, prefixed with chat_. Returned by the List chats endpoint.

messageIdRequiredstring

Unique identifier of the message — the id returned when you send a message or by the List messages endpoint. Outbound messages use a msg_ id; inbound (received) messages use the id the List endpoint exposes for that row. Both are addressable.

Headers

AuthorizationRequiredstring

Your API key, sent as a bearer token: Authorization: Bearer <api_key>. Editing this stays in sync with the API key box on the right.

Bearer

Returns

dataoptionalMessage
idoptionalstring

Message id (msg_...).

chat_idoptionalstring
channel_idoptionalstring
channel_typeoptionalstring
"blooio""twilio""whatsapp""whatsapp_business""rcs_business"
protocoloptionalstring

Transport state or resolved wire service; never null. pending = accepted and dispatched, wire service not resolved yet; imessage / rcs / sms = the device-confirmed transport (iMessage blue bubble, RCS, or SMS/MMS green bubble); whatsapp = sent over P2P WhatsApp; whatsapp_business = sent over the WhatsApp Business Platform (WABA); unknown = accepted but the transport could not be resolved before the tracking window closed (see error).

"pending""unknown""imessage""sms""rcs""whatsapp""whatsapp_business"
directionoptionalstring
"inbound""outbound"
typeoptionalstring

Content type, e.g. text, media, poll.

textoptionalstring | null

The plain text of the message — what the recipient actually sees. On a rich-text message the styling delimiters are NOT included here; see formatted_text.

formatted_textoptionalstring

Markdown for a rich-text (bold/italic/underline/strikethrough) message. Omitted entirely when the message carries no styling, so its presence is how you detect rich text. Present in both directions: on an outbound send made with format: "markdown", and on an inbound iMessage whose sender styled their text — so styling a customer applied in Messages arrives here even though your integration never asked for it. Always a normalized re-serialization of the message's actual styling rather than an echo of the source string: bold is spelled **, italic *, underline ++, strikethrough ~~, and any character that would otherwise read as a delimiter is backslash-escaped. Re-sending this value verbatim with format: "markdown" reproduces the same styled message. Blooio iMessage only. This is the SAME field delivered on the message webhooks, so a message reads identically via REST or webhook.

statusoptionalstring

Delivery lifecycle state: queued (accepted, awaiting dispatch), sent (handed to the channel; protocol resolves around here), delivered (delivery receipt received), read (read receipt received), failed (see error), superseded (row replaced by an idempotency retry or a poll-vote supersession). Inbound messages surface via the event feed / webhooks with received.

provider_message_idoptionalstring | null
reply_to_message_idoptionalstring | null
erroroptionalobject | null
attachmentsoptionalobject[]

Ordered attachments on the message. Each entry is retrievable directly: url (servable, decrypted URL — inbound Apple/ media is downloaded, decrypted, and re-hosted before this is populated), media_type (content type), size (bytes), and an optional caption. Always present (empty array when there are none). Matches the webhook attachments shape exactly.

Array of object

urloptionalstring | null
media_typeoptionalstring | null
sizeoptionalinteger | null
captionoptionalstring | null
interactiveoptionalobject

Structured interactive content, present on interactive messages. For an inbound reply this is the customer's actual selection (role: reply): kind (quick_reply/list_picker/time_picker/form/…), chosen (the selected option titles / time slots / flattened answers) and, for Form Messages, a structured responses array (per-page question + typed answers per §17.4) — not just a display string, and never null on an interactive reply. For an outbound send it is the prompt that was sent (role: prompt). The message's text remains a deterministic flattened convenience summary alongside this structure. This is the SAME object delivered on the message.received webhook, so a message reads identically via REST or webhook.

created_atoptionalinteger
updated_atoptionalinteger

Response codes

200A message
401Your API key is missing or invalid. Pass it as a bearer token.
404No message was found with the provided `chatId`.

Sends a live request with your values and shows the real response below. Your key is stored only in this browser.

Request
curl -X GET https://api.blooio.com/v4/chats/chat_a1b2c3d4/messages/msg_a1b2c3d4 \
Response objectexample
{  "data": {    "id": "msg_a1b2c3d4",    "chat_id": "chat_a1b2c3d4",    "channel_id": "ch_a1b2c3d4",    "channel_type": "blooio",    "protocol": "pending",    "direction": "inbound",    "type": "string",    "text": "Hello from Blooio!",    "formatted_text": "string",    "status": "active",    "provider_message_id": "msg_a1b2c3d4",    "reply_to_message_id": "msg_a1b2c3d4",    "error": {},    "attachments": [      {        "url": "https://example.com",        "media_type": "string",        "size": 50,        "caption": "Hello from Blooio!"      }    ],    "interactive": {},    "created_at": 0,    "updated_at": 0  }}