GET
/api/public/v1/conversations/{conversationId}/messages

List messages in a conversation

Top-level messages, newest first. **Cursor-paginated, not offset-paginated**: a busy channel gains messages while you page, and an offset would hand you the same one twice. Pass the oldest id you received back as `cursor` to get the page before it; a null `nextCursor` means you have reached the start of the conversation. Thread replies are not included. A message with `replyCount` above zero has them, and they hang off that message. A public channel is readable by anyone in the company even without joining; a private one, a DM and a group need membership. An archived channel is readable only with `threads:admin`.

Required scope

The access token must carry this scope. A token missing it gets 403 Forbidden. Grant them to an API client under Settings → Company → API, and to a teammate under Employee → Permissions.

threads:read

Path Parameters

NameTypeRequiredDescription
conversationIdstringRequiredConversation ID.

Query Parameters

NameTypeRequiredDescription
cursorstringOptionalA message id. Returns the page older than it.
limitnumberOptional1-100.Default: 30
GETExample request
curl
curl -X GET "https://www.pxb.app/api/public/v1/conversations/{conversationId}/messages" \
  -H "Authorization: Bearer your_access_token"
200Example response
json
{
  "message": "Messages retrieved successfully!",
  "content": {
    "messages": [
      {
        "id": "msg_9931",
        "conversationId": "cnv_5150",
        "authorEmployeeId": "emp_12ab",
        "parentMessageId": null,
        "content": "Deploying the billing export now — <@emp_44f1> heads up.",
        "type": "TEXT",
        "replyCount": 2,
        "lastReplyAt": "2026-08-29T18:22:00.000Z",
        "editedAt": null,
        "deletedAt": null,
        "pinnedAt": null,
        "attachments": [],
        "reactions": [],
        "mentions": [
          {
            "employeeId": "emp_44f1"
          }
        ],
        "createdAt": "2026-08-29T18:10:00.000Z"
      }
    ],
    "nextCursor": "msg_9800",
    "hasMore": true
  }
}
403Example response
json
{
  "message": "You are not a member of this conversation."
}

In the console

The same thing done by hand, for anyone comparing the API against the screen they already use.

Threads
/threads
  1. Open a conversation from the sidebar.