BetaThe V4 API is in beta — endpoints and functionality may change.

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, AMB 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. 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 '{
    "content": { "type": "text", "text": "Following up" }
  }'
Try it

No 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": { "identifier": "+15551234567" }
  }'
Try it

Response:

{
  "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
  • Polls (also available as message content.type: "poll")
  • Participants (group-capable channels only)

State

Chats are typically open or closed. Closed chats (for example AMB 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.