Messaging
Conversations
Conversations is the messaging module: one thread per contact and channel, with the same message, participant and delivery-status shapes for SMS (channel_type 1), WhatsApp (2) and MMS (3). This guide covers the thread endpoints, delivery statuses, assignment rules, webhooks and prices. What each channel needs before you can send is in its own guide: Conversations / SMS (credit, sender names, templates, MMS, the legacy history endpoints) and Conversations / WhatsApp (sender, templates, media, the 24-hour window). Forwarding inbound SMS to email is configured in the portal (Settings → SMS).
Vocabulary
- A conversation has an
id(UUID), achannel_type, thesender_idit is sent from (your sender name or number),participants(participant_typephone_number,emailoruser;participant_id;is_system_userfor your own users),is_group,assigned_to_id/assigned_department_id,is_pinned,is_active(falseonce archived),unread_count,last_message_atand, for WhatsApp,expires_at(the end of the 24-hour reply window).channelslists every channel the same contact has written on. - A message has
direction(inbound/outbound),message_type(0 text, 5 image, 6 video, 7 file, 8 location, 9 audio, 10 sticker, 11 contact),content,content_url,attachments(one entry per media file withcontent_url,thumbnail_url,mime_type,file_size),metadata(template_idandtemplate_variablesfor a template,location,media, andmedia_errorwhen an inbound file could not be fetched),scheduled_for,is_draftandstatuses: one row per recipient withstatus(0 pending, 1 sent, 2 delivered, 3 read, 4 failed, 5 scheduled),error_code,error_description.
Workflow (what the portal does)
- The inbox:
GET /v2/conversationslists the account's threads, newest activity first. Filters:search(number, name or text),channel(1, 2 or 3),from_date/to_date(Y-m-d, the portal defaults to the last 31 days),status(last message status, 0–5),assigned_to_id,is_active(0to include archived threads),is_group,unread=1,unassigned=1,expires_in_hours(WhatsApp windows closing soon; the last three drop pagination and return up to 500 rows),sorts(comma-separated,-for descending, for exampleis_pinned,-last_message_at),page,per_page(default 15). The response is paginated:data,total,per_page,current_page,last_page,from,to.GET /v2/conversations/unread-countis the badge counter. - Open a thread:
GET /v2/conversations/{conversation}returns the conversation withparticipantsand its non-draftmessagesin chronological order, and marks it read for the calling user. WhatsApp messages are included only when the account has the WhatsApp feature. - Reply:
POST /v2/conversations/{conversation}/messageswithcontent, or media ascontent_url/content_file(WhatsApp) ormedia_ids(MMS), or a template asmetadata.template_idplusmetadata.template_variables. Optionalscheduled_for,is_draft,opt_in/opt_out(SMS), andchannel_typeto pick the channel on a thread that has both SMS and WhatsApp. Answers201with the message; an archived thread is restored.402means no credit,400carries the domaincodeof a failed send (see the SMS guide),422a validation failure or a closed WhatsApp window. - Start a thread:
POST /v2/conversationswithchannel_type,sender_id, eitherparticipants[]or, for SMS campaigns,contacts(comma-separated numbers),groups(contact group ids) ormessage_contacts(reuse the recipients of an earlier message), andmessage(content,content_url,content_file,media_ids,metadata.template_id,metadata.template_variables,scheduled_for). An existing thread with the same contact is reused. A single recipient answers201with the conversation; a bulk send answers201withsuccess_count,failed_count,total_countand, when the landline filter dropped numbers,warning_code,warningandwarning_detail. - Schedule and cancel:
scheduled_forisY-m-d H:i:s, must be in the future and is read in the user's timezone (orX-Timezone). The message sits with status 5 until delivery;DELETE /v2/conversations/{conversation}/messages/{message}cancels it and refunds the reserved credit. - Organise:
PATCH …/archive(no body),PATCH …/pin(is_pinned, omit to toggle),PATCH …/assign(user_idordepartment_id,nullto unassign; account admin),PATCH …/read-status(statusreadorunread). - Delivery:
GET /v2/conversations/messages/{messageId}is one message or, withis-bulk=1, the bulk group it belongs to;POST /v2/conversations/messages/{message}/statuseslists the per-recipient statuses of a message or bulk group (is-bulk,filter[search]by number,filter[status],type,start,length), each withstatus,error_code,error_descriptionandcost. - Rules:
GET /v2/conversations/settingsandPOST /v2/conversations/settings(account admin) hold, per channel key (sms,whatsapp),auto_assigningrules (numbers[]→assign_to {type: user|department, id}) andtime_to_respondrules (numbers[]→ minutes);available_numberslists the numbers you can put in a rule. The whole settings object is replaced on every save. - Be told, not poll:
POST /v2/webhook-subscriptionswithtypemessage_receivedormessage_sentsends every inbound or outbound message of any channel to your URL (payloads and delivery rules in the Webhooks guide). - Prices:
GET /v2/account/messaging-rates-countriesthenGET /v2/account/messaging-rates?country_code=IE: one row per channel (1 SMS, 2 WhatsApp withwa_message_type, 3 MMS) with the per-messagepricein the account currency.
Roles and access
- Any authenticated user can list, open, start and reply;
assignand the rules endpoints need an account admin (403otherwise). Opening a thread the user may not see answers403. - the WhatsApp for Business add-on enables channel 2 and the MMS option enables
media_idson channel 1; without them the input is ignored or answers code 6101. - The ISO dates option (per account) returns every timestamp as ISO 8601 in the requested
X-Timezone; without it the thread and message timestamps are ISO 8601 in UTC with microseconds (2026-05-01T13:30:00.000000Z) andX-Timezoneis ignored. See Dates and timezones.
Pitfalls
channel_type,message_typeand everystatusare integers;directionis a string.- One contact, one thread: a number that writes to you on SMS and on WhatsApp shares a conversation, with both channels in
channels. Sendchannel_typewith the reply, or the thread's default channel is used. - A WhatsApp thread with
expires_atin the past accepts templates only; see the WhatsApp guide. SMS threads haveexpires_at: null. - An inbound WhatsApp file that could not be fetched arrives as a message without
content_urland withmetadata.media_error.code(MEDIA_TOO_LARGE,UNSUPPORTED_MEDIA_TYPE,MEDIA_DOWNLOAD_FAILED,MEDIA_PROCESSING_FAILED,MEDIA_TOO_LARGE_PROVIDER). - The SMS group still serves the older inbox, timeline and sent-history endpoints the portal's SMS pages use; they return the same messages in DataTables-style shapes and are documented in the SMS guide. New integrations should read through this group.