Get a message
/chats/{chatId}/messages/{messageId}Path parameters
chatIdRequiredstringUnique identifier of the chat, prefixed with chat_. Returned by the List chats endpoint.
messageIdRequiredstringUnique 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
AuthorizationRequiredstringYour API key, sent as a bearer token: Authorization: Bearer <api_key>. Editing this stays in sync with the API key box on the right.
Returns
dataoptionalMessage
dataoptionalMessageidoptionalstringMessage id (msg_...).
chat_idoptionalstringchannel_idoptionalstringchannel_typeoptionalstring"blooio""twilio""whatsapp""whatsapp_business""rcs_business""amb"channel_addressoptionalstring | nullThe address of your own line on this channel (the sending/receiving number or alias, e.g. +15559876543). Same value regardless of direction; sender/recipient tell you which side of the conversation it is on.
protocoloptionalstringTransport 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); amb = sent over Apple Messages for Business; unknown = accepted but the transport could not be resolved before the tracking window closed (see error).
"pending""unknown""imessage""sms""rcs""whatsapp""whatsapp_business""amb"directionoptionalstring"inbound""outbound"senderoptionalstring | nullWho the message is FROM, direction-aware. On inbound this is the other party (the contact who messaged you, or in a group the participant who wrote it); on outbound this is your own line (channel_address). This is the SAME field delivered on the message webhooks, so a message reads identically via REST or webhook.
recipientoptionalstring | nullWho the message is TO, direction-aware. On inbound this is your own line (channel_address); on outbound this is the other party. The mirror of sender. Matches the message webhook shape.
contactoptionalContactSummary | nullThe other party (never your own line), regardless of direction — so you always know who the message is with. On an inbound group message it is the member who sent it; null on a message you sent to a group. Matches the message webhook shape.
contactoptionalContactSummary | nullThe other party (never your own line), regardless of direction — so you always know who the message is with. On an inbound group message it is the member who sent it; null on a message you sent to a group. Matches the message webhook shape.
ContactSummary
contact_idRequiredstring | nullThe contact (ct_...). null when no contact record matches the identifier.
identifierRequiredstringThe contact's identifier (phone number, email, or handle).
nameRequiredstring | nullThe contact's name. null when none is on file. On a webhook it is a snapshot from when the event happened; read the contact for current details.
groupoptionalGroupSummary | nullThe group, when the message is in a group chat. null in a 1:1 chat. Matches the message webhook shape.
groupoptionalGroupSummary | nullThe group, when the message is in a group chat. null in a 1:1 chat. Matches the message webhook shape.
GroupSummary
group_idRequiredstringGroup id (grp_...).
nameRequiredstring | nullThe group's name. null when it has none.
typeoptionalstringContent type, e.g. text, media, poll.
textoptionalstring | nullThe 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_textoptionalstringMarkdown 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.
statusoptionalstringDelivery 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.
reply_to_message_idoptionalstring | nullerroroptionalMessageErrorWhy the message failed; null unless it failed. On a blooio channel code is a MessageErrorCode and message describes it. On any other channel both are the provider's own error. See [Errors](/errors#v4-message-errors).
erroroptionalMessageErrorWhy the message failed; null unless it failed. On a blooio channel code is a MessageErrorCode and message describes it. On any other channel both are the provider's own error. See [Errors](/errors#v4-message-errors).
codeRequiredMessageErrorCode | string | nullmessageRequiredstring | nullA description of the failure.
attachmentsoptionalobject[]Ordered attachments on the message. Each entry is retrievable directly: url (servable, decrypted URL — inbound Apple Messages for Business 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.
attachmentsoptionalobject[]Ordered attachments on the message. Each entry is retrievable directly: url (servable, decrypted URL — inbound Apple Messages for Business 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 | nullmedia_typeoptionalstring | nullsizeoptionalinteger | nullcaptionoptionalstring | nullinteractiveoptionalobjectStructured 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.
imessage_appoptionalobjectPresent on imessage_app messages (custom app bubbles): the app's bundle_id, team_id and app_name, the app-state url its extension reads, caption / subcaption, and the bubble's session_id. The same object the message webhooks carry.
routingoptionalobjectApple Messages for Business only: the entry-point intent / group Apple attached to this message when the customer opened the conversation from a link or QR code. Present only on that message.
created_atoptionalintegerupdated_atoptionalintegerResponse codes
Sends a live request with your values and shows the real response below. Your key is stored only in this browser.
curl -X GET https://api.blooio.com/v4/chats/chat_a1b2c3d4/messages/msg_a1b2c3d4 \{ "data": { "id": "msg_a1b2c3d4", "chat_id": "chat_a1b2c3d4", "channel_id": "ch_a1b2c3d4", "channel_type": "blooio", "channel_address": "123 Main St", "protocol": "pending", "direction": "inbound", "sender": "string", "recipient": "string", "contact": { "contact_id": "ct_a1b2c3d4", "identifier": "+15551234567", "name": "Jane Doe" }, "group": { "group_id": "grp_a1b2c3d4", "name": "Jane Doe" }, "type": "string", "text": "Hello from Blooio!", "formatted_text": "string", "status": "active", "reply_to_message_id": "msg_a1b2c3d4", "error": { "code": null, "message": "Hello from Blooio!" }, "attachments": [ { "url": "https://example.com", "media_type": "string", "size": 50, "caption": "Hello from Blooio!" } ], "interactive": {}, "imessage_app": {}, "routing": {}, "created_at": 0, "updated_at": 0 }}