Recipe: show Clomni conversations in your own dashboard
Last updated: 11 November 2026 · 8 min read
This recipe shows Clomni conversations inside your company's own internal dashboard (ERP, CRM, order system). Your agents read the chat with a customer from your system, reply, resolve the conversation and assign it.
Steps
-
1
What you get
- The list of open conversations in your own dashboard, with counts and filters.
- A conversation's messages, replies, and private notes the customer never sees.
- Resolving and reopening conversations, assigning them to an agent or a team.
- Live updates of new messages and statuses by webhook.
-
2
Scopes you need
When creating the app pick the "Clomni in my own panel" preset and remove what you do not need:
conversations:read(medium): the conversation list and the conversation itself;conversations:write(medium): status, priority, labels;conversations:assign(medium): assign to an agent or a team;messages:read(medium): message text and files, themessage.*webhooks;messages:send(high): reply to the customer;notes:write(low): private notes;contacts:read,contacts:write(medium): contact details;inboxes:read,agents:read,teams:read,labels:read,canned_responses:read(low): filters and pickers.
The token owner is an administrator of the workspace, so the API returns every inbox and every conversation. Limit what your agents see inside your own dashboard. A reply sent through the API shows under the token owner's name in the conversation.
-
3
1. Conversation list
GET /v1/conversationsreturns pages of 25, newest activity first. Parameters:status(open,resolved,pending,snoozed,all, defaultopen),assignee_type(me,unassigned,assigned,all),inbox_id,team_id,labels[],q,page.curl "https://api.clomni.ai/v1/conversations?status=open&assignee_type=all&page=1" \ -H "Authorization: Bearer clomni_pat_xxx"
The counts are in
data.meta(mine_count,assigned_count,unassigned_count,all_count) and the page is indata.payload. A conversation'sidis the number the dashboard shows, and{conversation_id}in every conversation path is that number. -
4
2. A conversation's messages
curl "https://api.clomni.ai/v1/conversations/1042/messages" \ -H "Authorization: Bearer clomni_pat_xxx"
The answer has the last 20 messages, oldest first. For older ones send the smallest
idasbefore:?before=55120. An emptypayloadis the start of the history.message_type:0from the customer,1from an agent or the API,2a system event,3a template.status:sent,delivered,read,failed. -
5
3. Replies and private notes
curl -X POST "https://api.clomni.ai/v1/conversations/1042/messages" \ -H "Authorization: Bearer clomni_pat_xxx" \ -H "Content-Type: application/json" \ -d '{"content": "Hello Leyla, your order will be delivered today.", "content_attributes": {"client_echo_id": "panel-7f3a9c"}}'- The channel sends the message in the background; the result shows later in
status(themessage.updatedwebhook). - Put your own unique value in
content_attributes.client_echo_id: within 24 hours a request with the same value in the same conversation does not create a second message. Keep the value when you retry. - For a private note send
"private": true; the scope isnotes:write. The customer never sees it. - In a WhatsApp Cloud conversation
can_reply: falsemeans the 24 hour window is closed: a template is needed, see Recipe: send WhatsApp notifications and templates from your website.
- The channel sends the message in the background; the result shows later in
-
6
4. Status and assignment
Resolve or reopen (
conversations:write):curl -X POST "https://api.clomni.ai/v1/conversations/1042/toggle_status" \ -H "Authorization: Bearer clomni_pat_xxx" \ -H "Content-Type: application/json" \ -d '{"status": "resolved"}'Assign (
conversations:assign):{"assignee_id": 12}to an agent,{"team_id": 3}to a team,{"assignee_id": null}removes the agent.curl -X POST "https://api.clomni.ai/v1/conversations/1042/assignments" \ -H "Authorization: Bearer clomni_pat_xxx" \ -H "Content-Type: application/json" \ -d '{"assignee_id": 12}'Get the agent and team lists with
GET /v1/agentsandGET /v1/teams, and canned responses withGET /v1/canned_responses. -
7
5. Live updates
Instead of reloading the list every few seconds, set up a webhook on the developer portal. Topics for this dashboard:
message.created,message.updated,conversation.created,conversation.updated,conversation.status_changed,conversation.assigned. Delivery is guaranteed at least once, but your server can go down too: store the last successful time and callGET /v1/sync/messages?updated_since=<time>when you recover. See App webhooks and events: setup, topics, signature verification. -
8
Common mistakes
- The list is reloaded every few seconds and hits the rate limit. Use webhooks.
GET /v1/conversationsis paged through to copy every conversation.GET /v1/sync/conversationsis made for that.- A reply is retried without
client_echo_idorIdempotency-Keyand the customer gets two messages. status: sentis taken for "delivered". If the message did not go out it becomesfailedlater, with the reason incontent_attributes.external_error.- On a 422 only
error.codeis read. Endpoints' own validation errors still use the older shape:{"error": "..."}or{"message": "..."}. - The send limit is forgotten:
POST /v1/conversations/{conversation_id}/messagesallows 60 requests a minute per token.
All conversation and message endpoints: Scopes and endpoints: conversations and messages.