Skip to main content
POST

Authorizations

Authorization
string
header
required

An API key of one app, sent as Authorization: Bearer <key>. Keys start with fk_test_ (test mode: sandbox senders and test data only) or fk_live_ (live mode). Keep live keys on your server; never ship them in an app or page.

Headers

Idempotency-Key
string

A unique string (up to 255 characters) that makes this request safe to retry. A repeat with the same key within 24 hours returns the first answer instead of acting again. See "Idempotency" in the introduction.

Required string length: 1 - 255
Flow-Version
string<date>

The API version to use, as a date. Without it, the version pinned to your app when it was created is used.

Example:

"2026-11-01"

Path Parameters

conversation_id
string
required

The conversation's ID. A conversation ID, conv_ and a ULID.

Pattern: ^conv_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1"

Body

application/json

One piece of content to send into a conversation.

content
object
required

Text, both ways. With format markdown, Flow renders it in each channel's own formatting; a channel without formatting needs fallback.

reply_to
string

Send this as a reply to an earlier message in the same conversation. Telegram and iMessage show it as an inline reply; channels without inline replies send it as a normal message. Refused with not_found (param reply_to) when the target is not a message in this conversation, and with invalid_request (param reply_to) when the content is typing, read, reaction, edit or unsend, or when the target never reached the channel (for example, it failed). If the target fails after the send was accepted, the reply goes out as a normal message.

Pattern: ^msg_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"msg_01JB8ZD4M6P8R0T2V4X6Z8B0C2"

fallback

What to send when the channel cannot show content. Without it, such a send fails with unsupported_content; nothing is converted silently.

  • "auto": use the documented default for the content type (markdown becomes plain text, buttons become numbered text whose replies are matched back to the button IDs, a voice note becomes an audio file, a location becomes a maps link, a contact card becomes text, an effect becomes plain text, a reaction becomes the closest tapback or is skipped).
  • A Content object: send exactly this instead.

The message's delivered_as reports what was used.

Available options:
auto
channel_options
object

Unstable escape hatch. Extra channel parameters for how a message looks and notifies, for example {"parse_mode": "HTML"} on Telegram. Each channel has an allowlist: keys not on it are dropped, never passed to the channel, and the typed request always wins over a key that sets the same thing. Who receives the message and what it says always come from the typed request. Keys starting with _flow_ are reserved and refused with invalid_request. Flow does not validate the values, and they may break when a channel changes. Prefer typed content.

  • Telegram (Bot API parameters, on every send): parse_mode, entities, caption_entities, link_preview_options, disable_web_page_preview, show_caption_above_media, disable_notification, protect_content, allow_paid_broadcast, message_effect_id, has_spoiler, supports_streaming, duration, width, height, performer, horizontal_accuracy, foursquare_id, foursquare_type, google_place_id, google_place_type, vcard, is_big (reactions).
  • iMessage: on messages, subject, effect, preview, reply_to_id and contact_file; on typing content, typing (how long to show it, 1 to 60 seconds). Reactions, read receipts, edits and unsends take none.
  • WhatsApp: none yet; the channel is not live.
Example:
metadata
object

Up to 20 string pairs of your own, kept with the object and returned unchanged. Keys up to 40 characters, values up to 500.

Response

The message passed the gate and is queued for the channel.

One message in or out of a conversation, with its typed content and delivery status.

id
string
required

A message ID, msg_ and a ULID.

Pattern: ^msg_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"msg_01JB8ZD4M6P8R0T2V4X6Z8B0C2"

conversation
string
required

A conversation ID, conv_ and a ULID.

Pattern: ^conv_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1"

direction
enum<string>
required

in from the contact, out from your app.

Available options:
in,
out
status
enum<string>
required
  • received: inbound from the contact.
  • queued: accepted by the gate, waiting for its turn in the conversation.
  • sent: the channel accepted it.
  • delivered: it reached the contact's device, where the channel reports this.
  • read: the contact read it, where the channel reports this.
  • failed: it could not be sent; see error.
  • unsent: you unsent it.
Available options:
received,
queued,
sent,
delivered,
read,
failed,
unsent
content
object
required

Text, both ways. With format markdown, Flow renders it in each channel's own formatting; a channel without formatting needs fallback.

livemode
boolean
required

Whether the message belongs to live mode.

created_at
string<date-time>
required

When Flow received (inbound) or accepted (outbound) the message.

delivered_as
object

Present when what the contact sees differs from what you sent: the fallback was used, or the action was skipped because the channel has no equivalent. Absent when the content was shown as sent.

error
object

The details of an error.

channel_message_id
string

The channel's own ID for the message, once the channel accepted it.

reply_to
string
read-only

The Flow ID of the message this one replies to. For a sent message, the message the send named in reply_to. For a received message, the message it replies to inline (a Telegram reply; on iMessage, the thread's root message). Absent when the message is not a reply or the quoted message is not known to Flow.

Pattern: ^msg_[0-9A-HJKMNP-TV-Z]{26}$
Example:

"msg_01JB8ZD4M6P8R0T2V4X6Z8B0C2"

metadata
object

Up to 20 string pairs of your own, kept with the object and returned unchanged. Keys up to 40 characters, values up to 500.

updated_at
string<date-time>

When the status last changed.