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. 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. 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, the message.* 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. 3

    1. Conversation list

    GET /v1/conversations returns pages of 25, newest activity first. Parameters: status (open, resolved, pending, snoozed, all, default open), 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 in data.payload. A conversation's id is the number the dashboard shows, and {conversation_id} in every conversation path is that number.

  4. 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 id as before: ?before=55120. An empty payload is the start of the history. message_type: 0 from the customer, 1 from an agent or the API, 2 a system event, 3 a template. status: sent, delivered, read, failed.

  5. 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 (the message.updated webhook).
    • 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 is notes:write. The customer never sees it.
    • In a WhatsApp Cloud conversation can_reply: false means the 24 hour window is closed: a template is needed, see Recipe: send WhatsApp notifications and templates from your website.
  6. 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/agents and GET /v1/teams, and canned responses with GET /v1/canned_responses.

  7. 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 call GET /v1/sync/messages?updated_since=<time> when you recover. See App webhooks and events: setup, topics, signature verification.

  8. 8

    Common mistakes

    • The list is reloaded every few seconds and hits the rate limit. Use webhooks.
    • GET /v1/conversations is paged through to copy every conversation. GET /v1/sync/conversations is made for that.
    • A reply is retried without client_echo_id or Idempotency-Key and the customer gets two messages.
    • status: sent is taken for "delivered". If the message did not go out it becomes failed later, with the reason in content_attributes.external_error.
    • On a 422 only error.code is read. Endpoints' own validation errors still use the older shape: {"error": "..."} or {"message": "..."}.
    • The send limit is forgotten: POST /v1/conversations/{conversation_id}/messages allows 60 requests a minute per token.

    All conversation and message endpoints: Scopes and endpoints: conversations and messages.

Document