Endpoint ·
GET /conversation (detail) and GET /conversation/messages (thread)Read-only endpoints: they return information and change nothing. They are not sent inside the
actions array — you call them directly.GET /conversation answers what state it is in (24h window, mailbox, AI employee, labels) and who the contact is; GET /conversation/messages answers what was said, in what order, and by whom. The first one tells you which action is valid (for example, with the window closed you can only send a template); the second one lets you write the reply with the history in front of you.
Both identify the conversation with the same reference as the rest of the API, but passed as query params instead of in the body: exactly one of phone, username, whatsapp_user_id, or uuid, plus channel.
Conversation detail
phone— phone number in E.164 format. Normalized to digits before the lookup.username— the contact’s public WhatsApp username. Normalized (leading@stripped, case ignored).whatsapp_user_id— the contact’s BSUID (Meta’s opaque identity). Exact match, no normalization.uuid— 1TO1 AI internal UUID, if you already have it stored.channel— the channel’s public key (required on every request). List them withGET /channels. Case-insensitive. It pins the target channel; on the contact-based paths it restricts resolution to that channel, and withuuidthe resolver ignores it but the contract still requires it.
phone, username, whatsapp_user_id, or uuid must be present: zero or two identifiers return 400 (INVALID_REQUEST).
Response
window_open is the field that decides what you can send: when it is false, the only allowed message is an approved template. window_expires_at is null when the contact never wrote (the window never opened), and inbox_status is pending or resolved. mailbox and ai_employee are null when the conversation has no mailbox or AI employee assigned. is_tester flags whether the conversation was created from the testing module.
In
contact_info, whatsapp_user_id returns the real BSUID when one exists, falling back to the phone number until Meta migrates. If the value you get back is the phone number, send it as phone and not as whatsapp_user_id — the resolver matches BSUIDs by exact equality and would return 404.400INVALID_REQUEST— the reference carries zero or two identifiers, orchannelis missing.404CONVERSATION_NOT_FOUND— the conversation does not exist or belongs to another business.CHANNEL_NOT_FOUND— the channel key does not exist.409PHONE_NUMBER_AMBIGUOUS/USERNAME_AMBIGUOUS— several contacts share that phone number or username. Identify bywhatsapp_user_idoruuid.
Example
A pure read: it reports the state and changes nothing in the conversation."window_open": false, the right action is to send a template; if it has true, you can send text, media, or a quick reply.
Thread of messages and events
phone/username/whatsapp_user_id/uuid— the conversation reference, same rule: exactly one.channel— the channel’s public key (required).cursor— opaque cursor returned by the previous page innext_cursor(up to 512 characters). Do not reuse cursors across different endpoints.limit— items per page. Defaults to 50, maximum 100.
The thread paginates backwards in time: the first call returns the most recent items and
next_cursor moves towards the oldest ones. has_more set to true means there are older items left to read. Items within a page are in chronological order and that order is not configurable (there is no order parameter).Response
direction and author), what happened (event), with what content (content_type and body), and when (sent_at).
type—messageorevent. It discriminates the union: auto-generated SDKs expose it as a tagged union.direction—contact(sent by the person on the other side) orbusiness(it came from your business).author.type—customer,human,ai_employee,api_token,mass_campaign, orsystem.author.namecan benull.event— onmessageitems:message_receivedormessage_sent. Oneventitems:context_note,contact_name_updated,contact_phone_updated,contact_email_updated,scheduled_cancel, orconversion.content_type— onmessageitems:text,image,audio,video,document,location,sticker,contacts,template,interactive, orreaction. Alwaysnulloneventitems.status— onmessageitems:pending,sent,delivered,read, orfailed. Alwaysnulloneventitems.sent_at— the item’s business clock and the thread’s sort key. Always present.
400INVALID_REQUEST— invalid reference.INVALID_CURSOR— corrupted cursor or one not issued by this endpoint.404CONVERSATION_NOT_FOUND/CHANNEL_NOT_FOUND.409PHONE_NUMBER_AMBIGUOUS/USERNAME_AMBIGUOUS.
Example
Also a read: paging through the whole thread does not alter the conversation nor mark anything as read.next_cursor from the previous response: