TypeScript
curl
The objects
IDs are a prefix plus a ULID, so they sort by creation time.
One channel per conversation
- There is no cross-channel identity. The same person on Telegram and on WhatsApp is two contacts and two conversations. Flow never guesses that they are the same person, and never moves a conversation to another channel.
- Never assume a phone number. A Telegram contact has a user ID, a WhatsApp contact may have only a username, and an iMessage handle may be an email address. Read
contact.addressfor what the channel gives. - Reply where they wrote. Each event carries
conversation.channel, so one agent can serve every channel with the same code.
What a conversation tells you
window_open_until(WhatsApp only; absent on Telegram and iMessage): until when free-form messages may be sent. After it, only a template. Every event repeats it inconversation.window_open_until.type:direct(one contact, incontact) orgroup. Read a missingtypeasdirect.group(group conversations only): the group chat’sname, when it has one, and itsparticipants, each a contact. A group has nocontact; each inbound message’sfromsays who wrote. Group chats reach your app only from dedicated iMessage lines people add to them, and the API cannot create a group or change who is in it. See iMessage.opted_in: the contact wrote first, joined the sandbox, or you recorded their consent. Alwaystrueon groups.metadata: up to 20 string pairs of your own (for example your user ID), kept with the conversation.
Starting a conversation
Most conversations start when the person writes first. To write first, usePOST /v0/messages: a basic or template message, with kind saying which, plus a sender and an address on that sender’s channel. On Telegram that works only for people who already started your bot. iMessage lines reply only unless writing first is switched on for the line (imessage.can_initiate, available on request for dedicated lines). A start always makes a direct conversation.
curl
kind answers 422 unsupported_content with param kind: start with a basic message or a template, then send the other kinds into the conversation. to takes exactly one of contact, phone, telegram_user_id or handle. Starting a conversation spends the sender’s new-contact budget, and each channel has its own rule for who may be messaged first. See The send gate.
Related
- Message kinds: what each channel takes, one endpoint per kind.
- List conversations and list a conversation’s messages.