Reading conversations
Reading conversations
Read your WhatsApp history over HTTP: list threads (one per contact) and page through the messages in a thread. Use this to backfill, build your own inbox, or reconcile against the webhooks that push messages to you in real time.
Both endpoints need the whatsapp scope on your app key and work on native channels.
List threads
GET /channels/{id}/threads returns the channel’s conversations, newest activity first, paged with limit and offset.
curl "https://api.telenow.ai/api/app-whatsapp/channels/b1e2c3d4-…/threads?limit=20&offset=0" \
-H "Authorization: Bearer vai_app_…"
{ "success": true, "data": {
"threads": [
{
"id": "a17c9e0b-…",
"contactPhone": "+919876543210",
"contactName": "Asha Rao",
"lastMessageAt": "2026-07-18T09:14:22Z",
"lastInboundAt": "2026-07-18T09:14:22Z",
"lastBody": "Where is my order?",
"lastFromMe": false,
"unreadCount": 2,
"aiPaused": false,
"createdAt": "2026-07-01T11:02:10Z"
}
],
"total": 137,
"limit": 20,
"offset": 0,
"hasMore": true
} }
| Query param | Notes |
|---|---|
limit | Page size — optional, default 50, maximum 200 (larger values are clamped to 200) |
offset | Rows to skip — page with offset += limit while hasMore is true |
Thread fields:
| Field | Notes |
|---|---|
id | Thread id — use it in /threads/{id}/messages |
contactPhone | The customer’s number (E.164) |
contactName | WhatsApp profile name, if known |
lastMessageAt | Timestamp of the most recent message (in or out) |
lastInboundAt | Timestamp of the last inbound message — the anchor for the 24-hour window |
lastBody | Preview text of the last message |
lastFromMe | true if the last message was outbound |
unreadCount | Unread inbound messages on this thread |
aiPaused | true if AI auto-reply is paused for human takeover on this thread |
createdAt | When the thread was first created |
Page until hasMore is false. total is the full thread count for the channel.
Read messages in a thread
GET /threads/{id}/messages returns messages newest-first, paged backwards with a cursor (beforeId), not an offset.
curl "https://api.telenow.ai/api/app-whatsapp/threads/a17c9e0b-…/messages?limit=30" \
-H "Authorization: Bearer vai_app_…"
{ "success": true, "data": {
"threadId": "a17c9e0b-…",
"contactPhone": "+919876543210",
"messages": [
{
"id": "e5b2…",
"direction": "in",
"wamid": "wamid.HBgLMTQxNTU1NTAxMDAVAgAREg…",
"from": "+919876543210",
"body": "Here's the receipt you asked for",
"type": "image",
"sentBy": null,
"status": "delivered",
"content": { "media": { "id": "9f8e7d…", "mime": "image/jpeg", "caption": "receipt" } },
"media": { "mime": "image/jpeg", "filename": "receipt.jpg", "url": "https://…/media/9f8e7d…" },
"createdAt": "2026-07-18T09:14:22Z"
},
{
"id": "e5b1…",
"direction": "out",
"wamid": "wamid.HBgLMTQxNTU1NTAxMDAVBgAREg…",
"from": "+14155550100",
"body": "Sure — could you send the receipt?",
"type": "text",
"sentBy": "agent",
"status": "read",
"content": null,
"media": null,
"createdAt": "2026-07-18T09:13:05Z"
}
],
"limit": 30,
"hasMore": true
} }
| Query param | Notes |
|---|---|
limit | Page size — optional, default 50, maximum 200 (larger values are clamped to 200) |
beforeId | Cursor: the oldest message id you hold; returns messages strictly older than it |
Message fields:
| Field | Notes |
|---|---|
id | Message id — the cursor for beforeId |
direction | in (from the customer) or out (from you) |
wamid | WhatsApp message id — correlates with whatsapp.message.status events |
from | Sender’s number (E.164) |
body | Text body / caption |
type | text, image, audio, video, document, sticker, location, interactive, reaction, contacts |
sentBy | For outbound: who sent it (e.g. agent, a user id); null for inbound |
status | sent | delivered | read | failed (outbound) |
content | Structured extract for non-text types (media / location / reply / button / reaction / contacts), else null |
media | { mime, filename, url } when the message has an attachment, else null |
createdAt | Timestamp |
Paging backwards with beforeId
To load older messages, pass the id of the oldest message you have as beforeId — the endpoint walks backwards from there. Repeat while hasMore is true:
# Next (older) page: beforeId = the last message id from the previous page
curl "https://api.telenow.ai/api/app-whatsapp/threads/a17c9e0b-…/messages?limit=30&beforeId=e5b1…" \
-H "Authorization: Bearer vai_app_…"
{ "success": true, "data": {
"threadId": "a17c9e0b-…",
"contactPhone": "+919876543210",
"messages": [ /* the 30 messages immediately older than e5b1… */ ],
"limit": 30,
"hasMore": false
} }
When hasMore is false, you’ve reached the start of the thread.
Downloading media
When media is present, media.url points at the attachment. It resolves through GET /api/app-whatsapp/media/{id} (served as a nosniff attachment). See Sending & receiving media for the full media flow.
Reading does not clear unread
Reading a thread via the API does not clear its
unreadCountand does not send read receipts to the customer. Only opening the thread in the dashboard — or explicitly callingPOST /messages/read— marks messages read (blue ticks) and resets the badge.
So a backend that syncs history through these endpoints won’t accidentally “read” a customer’s messages out from under your support team. When your bot has actually handled a message and you want the customer to see blue ticks, call /messages/read deliberately — see Typing indicators & read receipts.
Endpoint reference
Base /api/app-whatsapp, scope whatsapp, native channels only.
| Method | Path | Purpose |
|---|---|---|
GET | /channels/{id}/threads?limit&offset | Conversations, paged → { threads, total, limit, offset, hasMore } (limit default 50, max 200) |
GET | /threads/{id}/messages?limit&beforeId | Message history, cursor-paged → { threadId, contactPhone, messages, limit, hasMore } (limit default 50, max 200) |
The dashboard equivalents are GET /api/orgs/{orgId}/whatsapp-hub/channels/{id}/threads and /threads/{tid}/messages with a user JWT.
Related
- Typing indicators & read receipts — mark read and clear the unread badge.
- Webhooks & events — get inbound messages pushed instead of polling.
- Sending & receiving media — download attachments referenced by
media.url. - WhatsApp API · WhatsApp product guide.