Workspace API

Client conversations

Client conversations endpoints of the Zanfia Workspace API, with schemas and code samples.

5 min readLast updated Jul 26, 2026

The direct-message inbox between your team and clients. Conversations are keyed by client id; the API key acts as its workspace user, so the caller must be active workspace staff. The broadcast route sends a real DM to every listed client - use it deliberately. All routes require a Authorization: Bearer header — see Authentication.

List conversations

GET/conversations

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Query Parameters

limit?integer

Page size (max 50, default 25).

cursor?string

Opaque cursor from a previous page.

unreadOnly?boolean

true keeps only threads with unread customer messages (filters the fetched page).

Response Body

application/json

application/json

curl -X GET "https://example.com/conversations"
{  "conversations": [    {      "clientId": "string",      "workspaceId": "string",      "customerName": "string",      "customerAvatarUrl": "string",      "unreadForStaff": true,      "needsReply": true,      "lastMessageAt": "string",      "lastMessage": {        "messageId": "string",        "text": "string",        "senderId": "string",        "fromStaff": true,        "sentAt": "string",        "type": "text",        "deleted": true,        "broadcastId": "string"      },      "createdAt": "string",      "lastCustomerMessageAt": "string",      "lastStaffMessageAt": "string"    }  ],  "nextCursor": "string"}
{  "error": "string"}

Send a broadcast DM

POST/conversations/broadcast

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

⚠️ Sends content as a DM to EVERY listed client (≤ 5000 recipients). Fan-out runs async via the background runner; poll the conversations list to observe delivery.

Response Body

application/json

application/json

curl -X POST "https://example.com/conversations/broadcast" \  -H "Content-Type: application/json" \  -d '{    "recipientIds": [      "string"    ],    "content": "string"  }'
{  "broadcast": {    "id": "string",    "workspaceId": "string",    "createdBy": "string",    "content": "string",    "recipientCount": 0,    "status": "pending",    "processedCount": 0,    "skippedCount": 0,    "failedCount": 0,    "notifyByEmail": true,    "createdAt": "string",    "completedAt": "string",    "triggerRunId": "string"  }}
{  "error": "string"}

Get a conversation

GET/conversations/{clientId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Response Body

application/json

application/json

curl -X GET "https://example.com/conversations/string"
{  "conversation": {    "clientId": "string",    "workspaceId": "string",    "customerName": "string",    "customerAvatarUrl": "string",    "unreadForStaff": true,    "needsReply": true,    "lastMessageAt": "string",    "lastMessage": {      "messageId": "string",      "text": "string",      "senderId": "string",      "fromStaff": true,      "sentAt": "string",      "type": "text",      "deleted": true,      "broadcastId": "string"    },    "createdAt": "string",    "lastCustomerMessageAt": "string",    "lastStaffMessageAt": "string"  }}
{  "error": "string"}

List messages

GET/conversations/{clientId}/messages

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Query Parameters

limit?integer

Page size (max 100, default 25).

cursor?string

Opaque cursor from a previous page.

Response Body

application/json

application/json

curl -X GET "https://example.com/conversations/string/messages"
{  "messages": [    {      "id": "string",      "conversationId": "string",      "senderId": "string",      "senderRole": "customer",      "senderName": "string",      "senderAvatarUrl": "string",      "content": "string",      "type": "text",      "attachments": [        {          "id": "string",          "originalName": "string",          "shortName": "string",          "size": 0,          "contentType": "string",          "duration": 0,          "extension": "string",          "url": "string",          "thumbUrl": "string",          "createdBy": "string",          "voice": {            "waveform": [              0            ],            "canonicalUrl": "string",            "processingStatus": "ready"          }        }      ],      "reactions": [        {          "emoji": "string",          "userId": "string",          "addedAt": 0        }      ],      "createdAt": "string",      "editedAt": "string",      "deletedAt": "string",      "broadcastId": "string"    }  ],  "nextCursor": "string"}
{  "error": "string"}

Send a message

POST/conversations/{clientId}/messages

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X POST "https://example.com/conversations/string/messages" \  -H "Content-Type: application/json" \  -d '{    "content": "string"  }'
{  "conversation": {    "id": "string",    "workspaceId": "string",    "customerName": "string",    "customerAvatarUrl": "string",    "lastMessage": {      "text": "string",      "senderId": "string",      "sentAt": "string",      "type": "text",      "messageId": "string",      "deleted": true    },    "createdAt": "string",    "updatedAt": "string",    "lastCustomerMessageAt": "string",    "lastStaffMessageAt": "string"  },  "message": {    "id": "string",    "conversationId": "string",    "senderId": "string",    "senderRole": "customer",    "senderName": "string",    "senderAvatarUrl": "string",    "content": "string",    "type": "text",    "attachments": [      {        "id": "string",        "originalName": "string",        "shortName": "string",        "size": 0,        "contentType": "string",        "duration": 0,        "extension": "string",        "url": "string",        "thumbUrl": "string",        "createdBy": "string",        "voice": {          "waveform": [            0          ],          "canonicalUrl": "string",          "processingStatus": "ready"        }      }    ],    "reactions": [      {        "emoji": "string",        "userId": "string",        "addedAt": 0      }    ],    "createdAt": "string",    "editedAt": "string",    "deletedAt": "string",    "broadcastId": "string"  }}
{  "error": "string"}

Edit a message

PATCH/conversations/{clientId}/messages/{messageId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

messageId*string

Message id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

curl -X PATCH "https://example.com/conversations/string/messages/string" \  -H "Content-Type: application/json" \  -d '{    "content": "string"  }'
{  "message": {    "id": "string",    "conversationId": "string",    "senderId": "string",    "senderRole": "customer",    "senderName": "string",    "senderAvatarUrl": "string",    "content": "string",    "type": "text",    "attachments": [      {        "id": "string",        "originalName": "string",        "shortName": "string",        "size": 0,        "contentType": "string",        "duration": 0,        "extension": "string",        "url": "string",        "thumbUrl": "string",        "createdBy": "string",        "voice": {          "waveform": [            0          ],          "canonicalUrl": "string",          "processingStatus": "ready"        }      }    ],    "reactions": [      {        "emoji": "string",        "userId": "string",        "addedAt": 0      }    ],    "createdAt": "string",    "editedAt": "string",    "deletedAt": "string",    "broadcastId": "string"  }}
{  "error": "string"}

Delete a message

DELETE/conversations/{clientId}/messages/{messageId}

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

messageId*string

Message id

Response Body

application/json

application/json

curl -X DELETE "https://example.com/conversations/string/messages/string"
{  "message": {    "id": "string",    "conversationId": "string",    "senderId": "string",    "senderRole": "customer",    "senderName": "string",    "senderAvatarUrl": "string",    "content": "string",    "type": "text",    "attachments": [      {        "id": "string",        "originalName": "string",        "shortName": "string",        "size": 0,        "contentType": "string",        "duration": 0,        "extension": "string",        "url": "string",        "thumbUrl": "string",        "createdBy": "string",        "voice": {          "waveform": [            0          ],          "canonicalUrl": "string",          "processingStatus": "ready"        }      }    ],    "reactions": [      {        "emoji": "string",        "userId": "string",        "addedAt": 0      }    ],    "createdAt": "string",    "editedAt": "string",    "deletedAt": "string",    "broadcastId": "string"  }}
{  "error": "string"}

Toggle a reaction

POST/conversations/{clientId}/messages/{messageId}/reactions

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

messageId*string

Message id

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Toggles the caller's reaction: present → removed, absent → added.

Response Body

application/json

application/json

curl -X POST "https://example.com/conversations/string/messages/string/reactions" \  -H "Content-Type: application/json" \  -d '{    "emoji": "string"  }'
{  "message": {    "id": "string",    "conversationId": "string",    "senderId": "string",    "senderRole": "customer",    "senderName": "string",    "senderAvatarUrl": "string",    "content": "string",    "type": "text",    "attachments": [      {        "id": "string",        "originalName": "string",        "shortName": "string",        "size": 0,        "contentType": "string",        "duration": 0,        "extension": "string",        "url": "string",        "thumbUrl": "string",        "createdBy": "string",        "voice": {          "waveform": [            0          ],          "canonicalUrl": "string",          "processingStatus": "ready"        }      }    ],    "reactions": [      {        "emoji": "string",        "userId": "string",        "addedAt": 0      }    ],    "createdAt": "string",    "editedAt": "string",    "deletedAt": "string",    "broadcastId": "string"  }}
{  "error": "string"}

Mark conversation read

POST/conversations/{clientId}/read

Authorization

bearerAuth
AuthorizationBearer <token>

API key from Dashboard → Integrations → API, MCP and CLI.

In: header

Path Parameters

clientId*string

Client id

Response Body

application/json

application/json

curl -X POST "https://example.com/conversations/string/read"
{  "readAt": 0}
{  "error": "string"}

Was this article helpful?

Related articles

Spotted something off? Tell us at support@zanfia.com.