Skip to content

Conversations

View as Markdown

The shared inbox: read threads, assign, resolve and reopen.

The shared inbox holds one conversation per customer and channel. Through the API you can route conversations from your own systems (a helpdesk, a CRM, an on-call rota), read threads, and close them, while your team keeps working in the portal.

How it works: Inbox & conversationsA conversation's life · Route conversations to the right person · Read a thread · Reply and close · Events

A conversation's life#

StateMeaning
botA flow or AI bot is answering
needs_agentWaiting for a person: the bot handed over, or the customer asked for someone
assignedGiven to a team member who has not replied yet
humanA person is handling it
snoozedParked until snoozed_until
resolvedClosed. If the customer writes again it reopens by itself

open is true for every state but resolved, and unread says whether the customer wrote since someone last read the thread.

Route conversations to the right person#

A common integration: when a conversation needs a person, pick who takes it in your system and assign it.

  1. Subscribe an endpoint to conversation.needs_agent.
  2. Choose a member from GET /members (viewers cannot be assigned).
  3. Assign with POST /conversations/{id}/assign:
JSON
{ "member_id": "usr_41" }

The member must be able to see the conversation's number or account; otherwise the answer is assignee_invalid rather than a thread nobody can open.

Read a thread#

  • GET /conversations with filters builds any queue: open=true&assignee=none is everything waiting for someone; customer=0501234567 finds one customer's thread.
  • GET /conversations/{id}/messages returns the messages in both directions, newest first. Internal notes between agents are never included.

Reply and close#

Reply with POST /messages, sending to the conversation's customer.address (and channel for Instagram or Messenger). The reply appears in the thread in the portal like any other.

Close with POST /conversations/{id}/resolve, and reopen with POST /conversations/{id}/reopen (unassigned, or to member_id). Every action you take is recorded in the conversation's history as the API, with the key that made it.

Events#

EventWhen
conversation.createdA customer started a new conversation
conversation.needs_agentIt is waiting for a person
conversation.assignedIt was assigned (by a person, a rule or the API)
conversation.resolvedIt was closed
conversation.reopenedA closed conversation became active again

message.received still arrives for every customer message, so you can mirror the thread in your own tool.

Endpoints

List conversations

gethttps://api.saei.automize.sa/v1/conversations
  • Scope: conversations:read
  • Live keys only

Threads in the shared inbox, newest first, on WhatsApp, Instagram and Messenger. Filter to build your own queue: open=true&assignee=none is everything waiting for someone.

Query parameters

  • limitintegeroptional

    How many objects to return, 1 to 100.

  • cursorstringoptional

    The next_cursor from the previous page.

  • openbooleanoptional

    true for unresolved conversations, false for resolved ones.

  • statestringoptional

    One ofbotneeds_agentassignedhumanresolvedsnoozed

  • channelstringoptional

    One ofwhatsappinstagrammessenger

  • assigneestringoptional

    A member id (usr_…), or none for unassigned.

  • customerstringoptional

    The customer's phone (any format) or Instagram / Messenger id.

  • unreadbooleanoptional
Response fields200
  • object"list"required
  • dataarray<Conversation>required
    Child fields (17)
    • idstringrequired
    • object"conversation"required
    • channelstringrequired

      One ofwhatsappinstagrammessenger

    • customerobjectrequired
      Child fields (3)
      • contact_idstring | nulloptional
      • addressstringoptional

        The phone (E.164) on WhatsApp; the customer's id on Instagram / Messenger. Send replies to this.

      • namestring | nulloptional
    • number_idstring | nulloptional
    • statestringrequired

      bot the automation is answering; needs_agent waiting for a person; assigned handed to someone who has not replied yet; human a person is on it; snoozed parked until snoozed_until; resolved closed.

      One ofbotneeds_agentassignedhumanresolvedsnoozed

    • openbooleanrequired
    • assigneeobject | nulloptional
      Child fields (2)
      • idstringoptional
      • namestring | nulloptional
    • unreadbooleanoptional
    • labelstring | nulloptional
    • last_customer_message_atstring | nulloptional
    • last_agent_message_atstring | nulloptional
    • reply_window_expires_atstring | nulloptional

      After this, only an approved template can reach the customer (WhatsApp) or nothing until they write (Instagram / Messenger).

    • resolved_atstring | nulloptional
    • snoozed_untilstring | nulloptional
    • created_atstring | nulloptional
    • updated_atstring | nulloptional
  • has_morebooleanrequired
  • next_cursorstring | nullrequired
Errors this can return3
Try it
curl -X GET https://api.saei.automize.sa/v1/conversations \
  -H "Authorization: Bearer $API_KEY"
Response

A page of conversations.

{
  "object": "list",
  "data": [
    {
      "id": "conv_311",
      "object": "conversation",
      "channel": "whatsapp",
      "customer": {
        "contact_id": "string",
        "address": "string",
        "name": "string"
      },
      "number_id": "string",
      "state": "bot",
      "open": false,
      "assignee": {
        "id": "string",
        "name": "string"
      },
      "unread": false,
      "label": "string",
      "last_customer_message_at": "2026-10-01T09:30:00Z",
      "last_agent_message_at": "2026-10-01T09:30:00Z",
      "reply_window_expires_at": "2026-10-01T09:30:00Z",
      "resolved_at": "2026-10-01T09:30:00Z",
      "snoozed_until": "2026-10-01T09:30:00Z",
      "created_at": "2026-10-01T09:30:00Z",
      "updated_at": "2026-10-01T09:30:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "string"
}

Get a conversation

gethttps://api.saei.automize.sa/v1/conversations/{id}
  • Scope: conversations:read
  • Live keys only

Path parameters

  • idstringrequired

    The object's id.

Response fields200
  • idstringrequired
  • object"conversation"required
  • channelstringrequired

    One ofwhatsappinstagrammessenger

  • customerobjectrequired
    Child fields (3)
    • contact_idstring | nulloptional
    • addressstringoptional

      The phone (E.164) on WhatsApp; the customer's id on Instagram / Messenger. Send replies to this.

    • namestring | nulloptional
  • number_idstring | nulloptional
  • statestringrequired

    bot the automation is answering; needs_agent waiting for a person; assigned handed to someone who has not replied yet; human a person is on it; snoozed parked until snoozed_until; resolved closed.

    One ofbotneeds_agentassignedhumanresolvedsnoozed

  • openbooleanrequired
  • assigneeobject | nulloptional
    Child fields (2)
    • idstringoptional
    • namestring | nulloptional
  • unreadbooleanoptional
  • labelstring | nulloptional
  • last_customer_message_atstring | nulloptional
  • last_agent_message_atstring | nulloptional
  • reply_window_expires_atstring | nulloptional

    After this, only an approved template can reach the customer (WhatsApp) or nothing until they write (Instagram / Messenger).

  • resolved_atstring | nulloptional
  • snoozed_untilstring | nulloptional
  • created_atstring | nulloptional
  • updated_atstring | nulloptional
Errors this can return3
Try it
curl -X GET https://api.saei.automize.sa/v1/conversations/conv_311 \
  -H "Authorization: Bearer $API_KEY"
Response

The conversation.

{
  "id": "conv_311",
  "object": "conversation",
  "channel": "whatsapp",
  "customer": {
    "contact_id": "ct_1052",
    "address": "+966501234567",
    "name": "سارة القحطاني"
  },
  "number_id": "num_3",
  "state": "assigned",
  "open": true,
  "assignee": {
    "id": "usr_41",
    "name": "نورة العتيبي"
  },
  "unread": true,
  "label": "شكوى",
  "last_customer_message_at": "2026-10-01T09:29:10Z",
  "last_agent_message_at": "2026-10-01T09:20:00Z",
  "reply_window_expires_at": "2026-10-02T09:29:10Z",
  "resolved_at": null,
  "snoozed_until": null,
  "created_at": "2026-09-28T14:00:00Z",
  "updated_at": "2026-10-01T09:29:10Z"
}

Assign a conversation

posthttps://api.saei.automize.sa/v1/conversations/{id}/assign
  • Scope: conversations:write
  • Live keys only

Hands the conversation to a team member. They must be able to see its number or account; viewers cannot be assigned.

Path parameters

  • idstringrequired

    The object's id.

Request body

  • member_idstringrequired

    From GET /v1/members.

Response fields200
  • idstringrequired
  • object"conversation"required
  • channelstringrequired

    One ofwhatsappinstagrammessenger

  • customerobjectrequired
    Child fields (3)
    • contact_idstring | nulloptional
    • addressstringoptional

      The phone (E.164) on WhatsApp; the customer's id on Instagram / Messenger. Send replies to this.

    • namestring | nulloptional
  • number_idstring | nulloptional
  • statestringrequired

    bot the automation is answering; needs_agent waiting for a person; assigned handed to someone who has not replied yet; human a person is on it; snoozed parked until snoozed_until; resolved closed.

    One ofbotneeds_agentassignedhumanresolvedsnoozed

  • openbooleanrequired
  • assigneeobject | nulloptional
    Child fields (2)
    • idstringoptional
    • namestring | nulloptional
  • unreadbooleanoptional
  • labelstring | nulloptional
  • last_customer_message_atstring | nulloptional
  • last_agent_message_atstring | nulloptional
  • reply_window_expires_atstring | nulloptional

    After this, only an approved template can reach the customer (WhatsApp) or nothing until they write (Instagram / Messenger).

  • resolved_atstring | nulloptional
  • snoozed_untilstring | nulloptional
  • created_atstring | nulloptional
  • updated_atstring | nulloptional
Errors this can return6
Try it
curl -X POST https://api.saei.automize.sa/v1/conversations/conv_311/assign \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "member_id": "usr_41"
}'
Response

The conversation, now assigned.

{
  "id": "conv_311",
  "object": "conversation",
  "channel": "whatsapp",
  "customer": {
    "contact_id": "string",
    "address": "string",
    "name": "string"
  },
  "number_id": "string",
  "state": "bot",
  "open": false,
  "assignee": {
    "id": "string",
    "name": "string"
  },
  "unread": false,
  "label": "string",
  "last_customer_message_at": "2026-10-01T09:30:00Z",
  "last_agent_message_at": "2026-10-01T09:30:00Z",
  "reply_window_expires_at": "2026-10-01T09:30:00Z",
  "resolved_at": "2026-10-01T09:30:00Z",
  "snoozed_until": "2026-10-01T09:30:00Z",
  "created_at": "2026-10-01T09:30:00Z",
  "updated_at": "2026-10-01T09:30:00Z"
}

List a conversation's messages

gethttps://api.saei.automize.sa/v1/conversations/{id}/messages
  • Scope: conversations:read
  • Live keys only

Every message in the thread, both directions, newest first. Internal notes between agents are never included.

Path parameters

  • idstringrequired

    The object's id.

Query parameters

  • limitintegeroptional

    How many objects to return, 1 to 100.

  • cursorstringoptional

    The next_cursor from the previous page.

Response fields200
  • object"list"required
  • dataarray<Message>required
    Child fields (28)
    • idstringrequired

      Unique id. Opaque: store it as a string of up to 64 characters.

    • object"message"required
    • livemodebooleanrequired
    • directionstringrequired

      outbound for messages you send, inbound for customer messages.

      One ofoutboundinbound

    • channelstringrequired

      One ofwhatsappinstagrammessenger

    • fromstring | nulloptional

      Sender, in E.164 for WhatsApp.

    • tostring | nulloptional

      Recipient, in E.164 for WhatsApp.

    • typestringrequired

      What kind of content the message carries.

    • textobjectoptional
      Child fields (1)
      • bodystringoptional
    • templateobjectoptional
      Child fields (4)
      • namestringoptional
      • languagestringoptional
      • variablesobjectoptional
      • bodystringoptional
    • imageobjectoptional

      Media messages carry link (or media_id), caption, filename and mime_type when known.

    • videoobjectoptional
    • audioobjectoptional
    • documentobjectoptional
    • stickerobjectoptional
    • locationobjectoptional
    • contactsarrayoptional
    • interactiveobjectoptional

      What you sent (type, body, buttons…), or for a customer's tap, reply: {id, title}.

    • reactionobjectoptional
    • statusstringrequired

      accepted → sent → delivered → read, or failed. Customer messages are received. Status changes arrive as webhook events.

      One ofacceptedsentdeliveredreadfailedreceived

    • errorobject | nulloptional

      Why delivery failed, when status is failed.

      Child fields (3)
      • codestring | nulloptional
      • titlestring | nulloptional
      • messagestring | nulloptional
    • referencestring | nulloptional

      Your own reference, echoed back from the send request and in every event.

    • conversation_idstring | nulloptional
    • provider_message_idstring | nulloptional

      WhatsApp's own message id (wamid).

    • contactobject | nulloptional
      Child fields (1)
      • namestring | nulloptional
    • contextobject | nulloptional

      For a reply, the message being replied to.

      Child fields (1)
      • provider_message_idstringoptional
    • created_atstring | nullrequired
    • updated_atstring | nulloptional
  • has_morebooleanrequired
  • next_cursorstring | nullrequired
Errors this can return3
Try it
curl -X GET https://api.saei.automize.sa/v1/conversations/conv_311/messages \
  -H "Authorization: Bearer $API_KEY"
Response

A page of messages.

{
  "object": "list",
  "data": [
    {
      "id": "msg_48213",
      "object": "message",
      "livemode": false,
      "direction": "outbound",
      "channel": "whatsapp",
      "from": "+966112345678",
      "to": "+966501234567",
      "type": "text",
      "text": {
        "body": "string"
      },
      "template": {
        "name": "string",
        "language": "string",
        "variables": {},
        "body": "string"
      },
      "image": {},
      "video": {},
      "audio": {},
      "document": {},
      "sticker": {},
      "location": {},
      "contacts": [],
      "interactive": {},
      "reaction": {},
      "status": "accepted",
      "error": {
        "code": "string",
        "title": "string",
        "message": "string"
      },
      "reference": "string",
      "conversation_id": "string",
      "provider_message_id": "string",
      "contact": {
        "name": "string"
      },
      "context": {
        "provider_message_id": "string"
      },
      "created_at": "2026-10-01T09:30:00Z",
      "updated_at": "2026-10-01T09:30:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "string"
}

Reopen a conversation

posthttps://api.saei.automize.sa/v1/conversations/{id}/reopen
  • Scope: conversations:write
  • Live keys only

Reopens a resolved conversation, unassigned in the team queue, or assigned to member_id.

Path parameters

  • idstringrequired

    The object's id.

Request body

  • member_idstring | nulloptional
Response fields200
  • idstringrequired
  • object"conversation"required
  • channelstringrequired

    One ofwhatsappinstagrammessenger

  • customerobjectrequired
    Child fields (3)
    • contact_idstring | nulloptional
    • addressstringoptional

      The phone (E.164) on WhatsApp; the customer's id on Instagram / Messenger. Send replies to this.

    • namestring | nulloptional
  • number_idstring | nulloptional
  • statestringrequired

    bot the automation is answering; needs_agent waiting for a person; assigned handed to someone who has not replied yet; human a person is on it; snoozed parked until snoozed_until; resolved closed.

    One ofbotneeds_agentassignedhumanresolvedsnoozed

  • openbooleanrequired
  • assigneeobject | nulloptional
    Child fields (2)
    • idstringoptional
    • namestring | nulloptional
  • unreadbooleanoptional
  • labelstring | nulloptional
  • last_customer_message_atstring | nulloptional
  • last_agent_message_atstring | nulloptional
  • reply_window_expires_atstring | nulloptional

    After this, only an approved template can reach the customer (WhatsApp) or nothing until they write (Instagram / Messenger).

  • resolved_atstring | nulloptional
  • snoozed_untilstring | nulloptional
  • created_atstring | nulloptional
  • updated_atstring | nulloptional
Errors this can return4
Try it
curl -X POST https://api.saei.automize.sa/v1/conversations/conv_311/reopen \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "member_id": "usr_41"
}'
Response

The reopened conversation.

{
  "id": "conv_311",
  "object": "conversation",
  "channel": "whatsapp",
  "customer": {
    "contact_id": "string",
    "address": "string",
    "name": "string"
  },
  "number_id": "string",
  "state": "bot",
  "open": false,
  "assignee": {
    "id": "string",
    "name": "string"
  },
  "unread": false,
  "label": "string",
  "last_customer_message_at": "2026-10-01T09:30:00Z",
  "last_agent_message_at": "2026-10-01T09:30:00Z",
  "reply_window_expires_at": "2026-10-01T09:30:00Z",
  "resolved_at": "2026-10-01T09:30:00Z",
  "snoozed_until": "2026-10-01T09:30:00Z",
  "created_at": "2026-10-01T09:30:00Z",
  "updated_at": "2026-10-01T09:30:00Z"
}

Resolve a conversation

posthttps://api.saei.automize.sa/v1/conversations/{id}/resolve
  • Scope: conversations:write
  • Live keys only

Closes the conversation. If the customer writes again it reopens by itself, and you get conversation.reopened.

Path parameters

  • idstringrequired

    The object's id.

Response fields200
  • idstringrequired
  • object"conversation"required
  • channelstringrequired

    One ofwhatsappinstagrammessenger

  • customerobjectrequired
    Child fields (3)
    • contact_idstring | nulloptional
    • addressstringoptional

      The phone (E.164) on WhatsApp; the customer's id on Instagram / Messenger. Send replies to this.

    • namestring | nulloptional
  • number_idstring | nulloptional
  • statestringrequired

    bot the automation is answering; needs_agent waiting for a person; assigned handed to someone who has not replied yet; human a person is on it; snoozed parked until snoozed_until; resolved closed.

    One ofbotneeds_agentassignedhumanresolvedsnoozed

  • openbooleanrequired
  • assigneeobject | nulloptional
    Child fields (2)
    • idstringoptional
    • namestring | nulloptional
  • unreadbooleanoptional
  • labelstring | nulloptional
  • last_customer_message_atstring | nulloptional
  • last_agent_message_atstring | nulloptional
  • reply_window_expires_atstring | nulloptional

    After this, only an approved template can reach the customer (WhatsApp) or nothing until they write (Instagram / Messenger).

  • resolved_atstring | nulloptional
  • snoozed_untilstring | nulloptional
  • created_atstring | nulloptional
  • updated_atstring | nulloptional
Errors this can return4
Try it
curl -X POST https://api.saei.automize.sa/v1/conversations/conv_311/resolve \
  -H "Authorization: Bearer $API_KEY"
Response

The resolved conversation.

{
  "id": "conv_311",
  "object": "conversation",
  "channel": "whatsapp",
  "customer": {
    "contact_id": "string",
    "address": "string",
    "name": "string"
  },
  "number_id": "string",
  "state": "bot",
  "open": false,
  "assignee": {
    "id": "string",
    "name": "string"
  },
  "unread": false,
  "label": "string",
  "last_customer_message_at": "2026-10-01T09:30:00Z",
  "last_agent_message_at": "2026-10-01T09:30:00Z",
  "reply_window_expires_at": "2026-10-01T09:30:00Z",
  "resolved_at": "2026-10-01T09:30:00Z",
  "snoozed_until": "2026-10-01T09:30:00Z",
  "created_at": "2026-10-01T09:30:00Z",
  "updated_at": "2026-10-01T09:30:00Z"
}

List team members

gethttps://api.saei.automize.sa/v1/members
  • Scope: conversations:read
  • Works in test mode

The people in this workspace, to assign conversations to. Viewers can read the inbox but cannot be assigned.

Query parameters

  • rolestringoptional

    One ofowneradmineditorviewercustomer_service

Response fields200
  • object"list"required
  • dataarray<Member>required
    Child fields (5)
    • idstringrequired
    • object"member"required
    • namestring | nulloptional
    • emailstring | nulloptional
    • rolestringrequired

      One ofowneradmineditorviewercustomer_service

  • has_morebooleanrequired
  • next_cursorstring | nullrequired
Errors this can return2
Try it
curl -X GET https://api.saei.automize.sa/v1/members \
  -H "Authorization: Bearer $API_KEY"
Response

Every member.

{
  "object": "list",
  "data": [
    {
      "id": "usr_41",
      "object": "member",
      "name": "نورة العتيبي",
      "email": "noura@example.com",
      "role": "customer_service"
    }
  ],
  "has_more": false,
  "next_cursor": null
}