curl --request GET \
--url https://api.flow.engineer/v1/conversations \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.flow.engineer/v1/conversations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.flow.engineer/v1/conversations"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.flow.engineer/v1/conversations"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"id": "conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1",
"app": "app_01JB8Z0A1C3E5G7J9K1M3P5R7T",
"channel": "telegram",
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T",
"contact": "ct_01JB8ZB2J4K6N8Q0S2V4W6Y8A0",
"livemode": true,
"opted_in": true,
"created_at": "2023-11-07T05:31:56Z",
"last_inbound_at": "2023-11-07T05:31:56Z",
"window_open_until": "2023-11-07T05:31:56Z",
"metadata": {}
}
],
"has_more": true
}{
"error": {
"type": "invalid_request",
"message": "limit must be between 1 and 100.",
"hint": "Pass limit between 1 and 100 (default 20), and page with after or before.",
"doc_url": "https://api.flow.engineer/docs/errors/invalid_request",
"param": "limit"
}
}{
"error": {
"type": "authentication",
"message": "No valid API key was given.",
"hint": "Send the header Authorization: Bearer fk_test_... (or fk_live_...); no key yet? Get a test key with curl -X POST https://api.flow.engineer/v1/sandbox/keys",
"doc_url": "https://api.flow.engineer/docs/errors/authentication"
}
}{
"error": {
"type": "new_contact_limit",
"message": "This sender has started its 15 new conversations for today.",
"hint": "Retry after 3600 seconds; replies into existing conversations still go.",
"doc_url": "https://api.flow.engineer/docs/errors/new_contact_limit",
"retry_after": 3600,
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T"
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"hint": "Send a template instead: POST /v1/messages with content.type=template.",
"doc_url": "https://api.flow.engineer/docs/errors/outside_window",
"param": "<string>",
"retry_after": 1,
"conversation": "conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1",
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T",
"channel_code": "<string>",
"request_id": "<string>"
}
}List conversations
Lists your app’s conversations in this mode, newest first.
curl --request GET \
--url https://api.flow.engineer/v1/conversations \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.flow.engineer/v1/conversations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.flow.engineer/v1/conversations"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.flow.engineer/v1/conversations"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"id": "conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1",
"app": "app_01JB8Z0A1C3E5G7J9K1M3P5R7T",
"channel": "telegram",
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T",
"contact": "ct_01JB8ZB2J4K6N8Q0S2V4W6Y8A0",
"livemode": true,
"opted_in": true,
"created_at": "2023-11-07T05:31:56Z",
"last_inbound_at": "2023-11-07T05:31:56Z",
"window_open_until": "2023-11-07T05:31:56Z",
"metadata": {}
}
],
"has_more": true
}{
"error": {
"type": "invalid_request",
"message": "limit must be between 1 and 100.",
"hint": "Pass limit between 1 and 100 (default 20), and page with after or before.",
"doc_url": "https://api.flow.engineer/docs/errors/invalid_request",
"param": "limit"
}
}{
"error": {
"type": "authentication",
"message": "No valid API key was given.",
"hint": "Send the header Authorization: Bearer fk_test_... (or fk_live_...); no key yet? Get a test key with curl -X POST https://api.flow.engineer/v1/sandbox/keys",
"doc_url": "https://api.flow.engineer/docs/errors/authentication"
}
}{
"error": {
"type": "new_contact_limit",
"message": "This sender has started its 15 new conversations for today.",
"hint": "Retry after 3600 seconds; replies into existing conversations still go.",
"doc_url": "https://api.flow.engineer/docs/errors/new_contact_limit",
"retry_after": 3600,
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T"
}
}{
"error": {
"type": "invalid_request",
"message": "<string>",
"hint": "Send a template instead: POST /v1/messages with content.type=template.",
"doc_url": "https://api.flow.engineer/docs/errors/outside_window",
"param": "<string>",
"retry_after": 1,
"conversation": "conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1",
"sender": "snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T",
"channel_code": "<string>",
"request_id": "<string>"
}
}Authorizations
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
The API version to use, as a date. Without it, the version pinned to your app when it was created is used.
"2026-11-01"
Query Parameters
An item ID. Returns the items that come after it in the list's order.
64An item ID. Returns the items that come before it in the list's order.
64How many items to return, 1 to 100.
1 <= x <= 100Only conversations on this sender.
A sender ID, snd_ and a ULID.
^snd_[0-9A-HJKMNP-TV-Z]{26}$"snd_01JB8Z4Q3V6W0R2N7C5H1M9K4T"
Only conversations with this contact.
A contact ID, ct_ and a ULID.
^ct_[0-9A-HJKMNP-TV-Z]{26}$"ct_01JB8ZB2J4K6N8Q0S2V4W6Y8A0"
Only conversations on this channel. A messaging channel.
telegram, whatsapp, imessage