Chats
Channel-scoped threads with opaque chat_ ids — create, send, and reply without using phone numbers as ids.
In v4, a chat is a messaging thread on a specific channel (sender). Ids look like chat_... — opaque and stable. Do not treat the recipient's phone number as the chat id (that was a common v2 pattern).
Mental model
| Channel | Your side of the wire (ch_... — a Blooio number, Twilio line, RCS Business sender, …) |
| Chat | The thread between that channel and a peer (chat_...) |
| Contact | The person, with one or more identities (ct_...) |
The same contact can have multiple chats — one per channel (for example SMS on Twilio and iMessage on Blooio are different chats).
Two ways to send
1. Agnostic send (find-or-create)
POST /messages takes to + content fields like text. Blooio picks a channel via priorities / hybrid, finds or creates the chat, and returns chat_id on the message.
Use this for cold outreach and simple bots.
2. Send into an existing chat
When you already have chat_id (from a webhook, a previous send, or create-chat):
curl -X POST https://api.blooio.com/v4/chats/chat_.../messages \
-H "Authorization: Bearer bl_live_..." \
-H "Content-Type: application/json" \
-d '{
"text": "Following up"
}'Try itNo from or to — the chat already knows the channel and peer.
Create a chat explicitly
Use this when you need the chat_id before the first message, or must pin a channel:
curl -X POST https://api.blooio.com/v4/chats \
-H "Authorization: Bearer bl_live_..." \
-H "Content-Type: application/json" \
-d '{
"channel_id": "ch_...",
"to": "+15551234567"
}'Try itResponse:
{
"id": "chat_...",
"channel_id": "ch_...",
"channel_type": "blooio",
"contact_id": "ct_...",
"identity_id": "cid_...",
"state": "open",
"created": true
}If the thread already exists, you get the same chat with "created": false (HTTP 200).
Chat-scoped actions
Once you have chat_id, these stay on the chat:
- List / send messages
- Typing indicators and read receipts (where the channel supports them)
- Reactions on a message
- Share contact card
- Focus status and Notify Anyway (direct Blooio chats)
- Polls (also available as the top-level
pollfield on a send) - Participants (group-capable channels only)
Focus
On a direct Blooio chat, GET /chats/{chatId}/focus reports whether the other person has notifications silenced by a Focus: silenced, none, or unknown. When they are silenced, POST /chats/{chatId}/messages/{messageId}/notify breaks through for an iMessage you sent, like tapping Notify Anyway in Messages. Notify Anyway cannot be undone, and no API can turn someone else's Focus on or off.
curl https://api.blooio.com/v4/chats/chat_.../focus \
-H "Authorization: Bearer bl_live_..."
curl -X POST https://api.blooio.com/v4/chats/chat_.../messages/msg_.../notify \
-H "Authorization: Bearer bl_live_..."State
Chats are typically open or closed. Closed chats (for example closed by the user) reject new sends with a conflict such as 409 chat_closed_by_user. Patch state with PATCH /chats/{chatId} when your product needs to mark a thread closed.
Webhooks
Inbound and lifecycle events include chat_id (and often a hydrated message or chat in data). Persist chat_id from the first event or send response and use it for all follow-ups.