Send a message
/messagesThe primary endpoint for starting a message. The common send is entirely scalar: { "from": "+15551230001", "to": "+15551234567", "text": "Hello" }. from is one optional string: 1. Phone number — "from": "+15551230001" selects your exact numbered channel with that address.
2. Alias — "from": "support" selects the non-numbered channel (RCS Business) with that organization-wide alias.
3. Channel id — "from": "ch_..." is the advanced exact-channel form.
4. Automatic — omit from to use the key's default priority / automatic routing. Advanced routing controls (each mutually exclusive with from): "priority_id": "priority_..." routes through an explicit priority; "channel_type": "blooio" constrains automatic/priority routing to one type; "hybrid": true (or a representative phone number string) requests hybrid Twilio-first / Blooio-after-reply routing. Priority routing is history-first and content-aware. Poll content currently routes only through Blooio. Existing groups require an exact sender whose channel owns the group or a hybrid sender that owns that channel. Returns the resolved scalar from plus the chosen channel_id, chat_id, and routing explanation.
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.
Idempotency-KeyoptionalstringOptional key for safe retries. Replaying the same key with an identical body returns the original result; a different body returns 409. Use a unique value (such as a UUID) per logical request.
Body parameters
JSONtextoptionalstringPlain text message. May be combined with attachments (sent as media with a caption).
attachmentsoptionalstring[]Public https media URLs. May be combined with text.
rich_linkoptionalobjectA tappable rich link bubble (Blooio /).
rich_linkoptionalobjectA tappable rich link bubble (Blooio /).
urlRequiredstringtitleoptionalstringpolloptionalobjectA native Blooio poll. Routed sends automatically consider only poll-capable channels.
polloptionalobjectA native Blooio poll. Routed sends automatically consider only poll-capable channels.
titleRequiredstringoptionsRequiredstring[]interactiveoptionalobjectInteractive content (WhatsApp Business / RCS). Requires kind.
interactiveoptionalobjectInteractive content (WhatsApp Business / RCS). Requires kind.
kindRequiredstringtemplateoptionalobjectTemplate content (WhatsApp Business).
templateoptionalobjectTemplate content (WhatsApp Business).
template_idoptionalstringpartsoptionalobject[]Ordered text/media parts sent as one multipart message (Blooio only).
partsoptionalobject[]Ordered text/media parts sent as one multipart message (Blooio only).
Array of object
textoptionalstringurloptionalstringreply_tooptionalstringMessage id to reply to. Applies to the whole outgoing message.
effectoptionalstringiMessage screen/bubble effect (Blooio, text only).
link_previewoptionalLinkPreview
link_previewoptionalLinkPreviewimageUrloptionalstringtitleoptionalstringfromoptionalFromThe sender as a single string: a phone number (any common format; matched to your exact numbered channel), a channel alias (organization-wide name of a non-numbered channel), or an exact channel id (ch_...). Omit it for automatic routing. If a phone number ever matches more than one active channel type, the send fails with 409 ambiguous_from and the exact ch_... id must be used instead.
priority_idoptionalstringRoute through an explicit priority (priority_...). Mutually exclusive with from.
channel_typeoptionalstring"blooio""twilio""whatsapp""whatsapp_business""rcs_business"hybridoptionalboolean | stringHybrid (Twilio-first / Blooio-after-reply) routing. true uses the calling key's hybrid configuration; a phone number string selects the hybrid owner of that representative number. Mutually exclusive with from and priority_id.
hybridoptionalboolean | stringHybrid (Twilio-first / Blooio-after-reply) routing. true uses the calling key's hybrid configuration; a phone number string selects the hybrid owner of that representative number. Mutually exclusive with from and priority_id.
toRequiredRecipientA recipient: a raw identifier string (phone/email/opaque provider id), an array of identifier strings (multiple recipients), an existing { group_id } with an exact or hybrid owner sender, or (for routed sends) a { contact_id }. A contact_id enables cross-channel-type routing via the contact's identities; a bare identifier reaches phone/email-addressable channels only.
toRequiredRecipientA recipient: a raw identifier string (phone/email/opaque provider id), an array of identifier strings (multiple recipients), an existing { group_id } with an exact or hybrid owner sender, or (for routed sends) a { contact_id }. A contact_id enables cross-channel-type routing via the contact's identities; a bare identifier reaches phone/email-addressable channels only.
dry_runoptionalbooleanValidate and route only; do not send.
Returns
idoptionalstringchat_idoptionalstringchannel_idoptionalstringchannel_typeoptionalstring"blooio""twilio""whatsapp""whatsapp_business""rcs_business"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 WhatsApp; unknown = accepted but the transport could not be resolved before the tracking window closed (see error).
"pending""unknown""imessage""sms""rcs""whatsapp"fromoptionalstring | nullThe resolved sender as a human value: the sending channel's phone number (numbered channels) or alias (non-numbered channels). This is the primary sender reference; channel_id remains available for exact follow-up and audit.
directionoptionalstring"inbound""outbound"typeoptionalstringstatusoptionalstringInitial lifecycle state for the send: normally queued (accepted for delivery), or failed if rejected before dispatch. Later transitions (sent → delivered / read, or failed) are reported via the message status endpoint and message.* webhooks.
group_idoptionalstringExisting group id for a group-targeted send.
hybridoptionalobjectHybrid routing phase and optional transition placement.
erroroptionalobject | nullfallbackoptionalobjectPresent when a send could not be delivered on the requested channel and a different channel should be tried.
fallbackoptionalobjectPresent when a send could not be delivered on the requested channel and a different channel should be tried.
recommendedoptionalbooleanTrue when falling back to another channel is recommended.
reasonoptionalstringtooptionalstringRecipient identifier. Present only on per-recipient items inside a fan-out (FanOutResult) response.
dry_runoptionalbooleanwould_sendoptionalbooleanpreviewoptionalobjectpolloptionalobject
polloptionalobjecttitleoptionalstringoptionsoptionalstring[]routingoptionalRoutingMetadataHow Blooio selected the concrete sender channel.
routingoptionalRoutingMetadataHow Blooio selected the concrete sender channel.
modeoptionalstring"explicit""priority""hybrid"channel_typeoptionalstring"blooio""twilio""whatsapp""whatsapp_business""rcs_business"numberoptionalstringaliasoptionalstringpriority_idoptionalstringpriorityoptionalintegerResponse codes
Sends a live request with your values and shows the real response below. Your key is stored only in this browser.
curl -X POST https://api.blooio.com/v4/messages \{ "id": "obj_a1b2c3d4", "chat_id": "chat_a1b2c3d4", "channel_id": "ch_a1b2c3d4", "channel_type": "blooio", "protocol": "pending", "from": "+15551234567", "direction": "inbound", "type": "string", "status": "active", "group_id": "grp_a1b2c3d4", "hybrid": {}, "error": {}, "fallback": { "recommended": false, "reason": "string" }, "to": "+15551234567", "dry_run": false, "would_send": false, "preview": {}, "poll": { "title": "Example title", "options": [ "string" ] }, "routing": { "mode": "explicit", "channel_type": "blooio", "number": "+15551234567", "alias": "string", "priority_id": "obj_a1b2c3d4", "priority": 0 }}