Inbox, contacts & segments
Everything your team does in the dashboard's WhatsApp inbox — assigning and resolving conversations, keeping contact records, saving audiences, quick replies, the business profile — is also available over HTTP with your org API key (X-API-Key: vai_live_…). App keys don't reach these routes.
All paths below are under https://api.telenow.ai/api/orgs/{orgId}/whatsapp-hub unless noted. Responses use the standard { "success": true, "data": … } envelope with snake_case fields. Any change needs an owner, admin or developer key; the role the key's creator needs is noted per route.
Manage threads
A thread is one conversation with one contact on one number. List them with GET /channels/{channelId}/threads (filter by status, assigned, q, tag); manage each one with:
| Method | Path | Body | Returns |
|---|---|---|---|
PUT | /threads/{threadId}/assign | { "user_id": "<user uuid>" } — null or omitted unassigns | { assignedTo } |
PUT | /threads/{threadId}/status | { "status": "open" | "pending" | "resolved" | "snoozed", "snoozed_until"? } | { status } |
PUT | /threads/{threadId}/pause | { "paused": true } — pause the AI agent on this thread | { success } |
curl -X PUT https://api.telenow.ai/api/orgs/{orgId}/whatsapp-hub/threads/{threadId}/status \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "status": "snoozed", "snoozed_until": "2026-07-19T09:00:00Z" }'
- Assign only to someone in your workspace (
400 that person isn't in this workspaceotherwise).assigned=mineon the thread list means threads assigned to the key's creator. - Snooze needs a future
snoozed_until(RFC 3339); a snoozed thread reopens asopenwithin about a minute of that time. - Resolve — moving a thread into
resolvedsends the customer a rating request when CSAT is on for the number. - Any member can do all three (the creator role is M).
To reply inside a thread, see Text messages — POST /threads/{threadId}/send. A reply sent that way is what counts as the thread's first response for inbox health.
Inbox health
GET /channels/{channelId}/inbox-health?days=30&threshold_mins=60 (any member) returns response-time numbers for one number:
{ "success": true, "data": {
"health": {
"median_first_response_secs": 312.5,
"awaiting_reply": 4,
"awaiting_over_threshold": 1,
"resolved_in_window": 57,
"unassigned_open": 2
},
"windowDays": 30,
"thresholdMins": 60
} }
| Field | Meaning |
|---|---|
median_first_response_secs | Median time from a thread starting to its first reply from a person, for threads started in the window (null if none) |
awaiting_reply | Open threads whose last message is from the customer |
awaiting_over_threshold | Of those, how many have waited longer than threshold_mins |
resolved_in_window | Threads resolved in the last days |
unassigned_open | Open threads with nobody assigned |
days is 1–365 (default 30); threshold_mins is 1–10,080 (default 60).
Contacts
Telenow keeps one contact record per phone number in your org. A record is created when a conversation with that number starts, and carries your own fields: a display name, notes, custom attributes, and tags (labels).
| Method | Path | What it does |
|---|---|---|
GET | /contacts?q&tag&limit&offset | List → { contacts, total, limit, offset }, most recent conversation first |
GET | /contacts/tags | Every label in use → { tags } |
GET | /contacts/{contactId} | One contact → { contact } |
GET | /contacts/by-phone/{phone} | Look up by number → { contact }; creates the record if the number has a conversation, otherwise 404 no conversation with that number here |
PATCH | /contacts/{contactId} | Edit → { contact } |
- List:
qsearches the number, display name and WhatsApp profile name;tagmatches one label exactly.limitis 1–200 (default 50). Each row addsprovider_name,thread_countandlast_message_at. - Contact fields:
id,phone,display_name,attributes,tags,notes,created_at,updated_at. - Any member can read and edit contacts.
curl -X PATCH https://api.telenow.ai/api/orgs/{orgId}/whatsapp-hub/contacts/{contactId} \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "display_name": "Asha Rao", "tags": ["vip", "mumbai"], "attributes": { "plan": "gold" } }'
Send only the fields you're changing — omitted fields are left alone:
| Field | Notes |
|---|---|
display_name, notes | Text, or null to clear |
attributes | An object — it replaces the whole attributes object |
tags | A list — it replaces the whole list. Each label is trimmed; blank labels and labels over 40 characters are dropped, duplicates are removed (ignoring case), and at most 50 are kept |
Segments
A segment is a saved audience — a rule over your contacts that you can preview and turn into broadcast recipients. Opted-out numbers are always excluded.
| Method | Path | What it does | Creator |
|---|---|---|---|
GET | /segments | List → { segments } | any member |
POST | /segments | Save { name, definition } → { segment } — saving an existing name replaces its rule | owner/admin/developer |
DELETE | /segments/{segmentId} | Delete | owner/admin/developer |
POST | /segments/preview | Count a rule before saving: { definition } or { segment_id } → { count, sample, capped } | any member |
The definition is an object; {} matches every contact.
| Key | Meaning |
|---|---|
tags | A list of labels (≤ 50). Contacts with any of them match — or all of them with "tagMode": "all" |
attributes | An object (≤ 50 keys); contacts whose attributes contain these exact values match |
quietForDays | 0–3,650 — leaves out anyone who has messaged you in the last N days |
curl -X POST https://api.telenow.ai/api/orgs/{orgId}/whatsapp-hub/segments/preview \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "definition": { "tags": ["vip"], "attributes": { "plan": "gold" } } }'
{ "success": true, "data": { "count": 1240, "sample": ["+919876543210", "…"], "capped": false } }
sample is the first five numbers. Previews count at most 5,000; capped is true once the count reaches 5,000. A broadcast takes at most 5,000 contacts from a segment — see Broadcasts.
Quick replies
Quick replies (canned replies) are saved message snippets your team inserts in the dashboard composer. Telenow never sends them on its own. Any member can manage them.
| Method | Path | Body | Returns |
|---|---|---|---|
GET | /canned-replies | — | { cannedReplies }, by title |
POST | /canned-replies | { title, body, shortcut? } | { cannedReply } |
PUT | /canned-replies/{replyId} | { title, body, shortcut? } — replaces the reply; leaving out shortcut clears it | { cannedReply } |
DELETE | /canned-replies/{replyId} | — | { deleted: true } |
title and body are required; body is at most 4,096 characters (WhatsApp's limit). shortcut is normalised — a leading / dropped, lowercased, only letters, digits, - and _ kept, at most 32 characters — and must be unique in your org (409 another quick reply already uses the shortcut /…).
Numbers in your inbox
GET /channels lists every number in your inbox (any member). Each row has id, kind (provider or baileys — WhatsApp Web), provider_id, label, phone, webhook_status, agent_id, ai_enabled and calling_enabled.
| Method | Path | What it does | Creator |
|---|---|---|---|
GET | /linkable-connections | WhatsApp connections in your integrations that aren't in the inbox yet → { connections } | any member |
POST | /channels | Add one: { "kind": "provider", "connection_id": "…", "label"? } → { channel, webhookUrl } | owner/admin |
GET | /channels/{channelId}/webhook | The inbound webhook URL and verify token to give a partner provider | any member |
DELETE | /channels/{channelId} | Remove a number from the inbox — it can be restored | owner/admin |
GET | /channels/removed | Removed numbers you can still restore | any member |
POST | /channels/{channelId}/restore | Restore a removed number → { channel } | owner/admin |
POST | /channels/{channelId}/purge | Permanently delete a removed number with its conversations, messages and broadcasts | owner/admin |
- Connecting a brand-new number (Meta Embedded Signup) and linking WhatsApp Web by QR need a dashboard login — see Connecting WhatsApp.
- Removing a WhatsApp Web number also unlinks the phone from Telenow.
- Purge can't be undone, and works only on a number that's already removed.
Business profile
The profile your customers see — about text, address, description, email, websites and business category — for a Meta Cloud number. Paths are under …/api/orgs/{orgId}/whatsapp-cloud/channels/{channelId}:
| Method | Path | What it does | Creator |
|---|---|---|---|
GET | /profile | { profile: { about, address, description, email, profile_picture_url, websites, vertical }, verticals } — verticals lists the allowed categories | any member |
POST | /profile | Update any of about, address, description, email, websites, vertical → { profile } | owner/admin |
curl -X POST https://api.telenow.ai/api/orgs/{orgId}/whatsapp-cloud/channels/{channelId}/profile \
-H "X-API-Key: vai_live_…" \
-H "Content-Type: application/json" \
-d '{ "about": "Order help, 9am–9pm", "websites": ["https://shop.example.com"] }'
websites holds at most two links, each starting with http:// or https://; vertical must be one of verticals. A request with no fields returns 400; if Meta refuses the update you get 502. The profile picture can't be changed through the API.
Related
- Reading conversations — thread lists and message history.
- Broadcasts — send a template to a segment.
- AI agent & calling — auto-reply, calling and customer ratings.
- API reference — every org-key route on one page.