/api/public/v1/conversations/{conversationId}Get a conversation
One conversation in full: its members, topic and description, the caller’s own read state, and the latest message. Readable by the same rule as its messages. A member always can; a public channel of the caller’s own company can be read without joining, and the support rota can read a Support channel. Without a membership there is no read state, so `isMember` is false and `unreadCount`, `unreadThreadCount`, `lastReadAt`, `markedUnread`, `isMuted` and `isFavorite` are null — never somebody else’s. A conversation outside the caller’s reach is a 404, the same as one that does not exist, so an id cannot be probed. An archived channel is readable only with `threads:admin`. `members` carries names and roles only — not login addresses or presence.
Required scope
The access token must carry this scope. A token missing it gets 403 Forbidden. Grant them to an API client under Dev Tools → API, to an assistant or CLI sign-in when you approve or edit it under Dev Tools, and to a teammate under Employee → Permissions.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversationId | string | Required | Conversation ID. |
curl -X GET "https://www.pxb.app/api/public/v1/conversations/{conversationId}" \
-H "Authorization: Bearer your_access_token"{
"message": "Conversation retrieved successfully!",
"content": {
"conversation": {
"id": "cnv_5150",
"referenceId": 88,
"type": "CHANNEL",
"title": "engineering",
"name": "engineering",
"topic": "Shipping things",
"description": null,
"visibility": "PUBLIC",
"isArchived": false,
"lastMessageAt": "2026-08-29T18:22:00.000Z",
"isSupport": false,
"isCrossCompany": false,
"memberEmployeeIds": [
"emp_12ab",
"emp_44f1"
],
"createdAt": "2026-01-08T09:00:00.000Z",
"isMember": true,
"unreadCount": 3,
"unreadThreadCount": 1,
"lastReadAt": "2026-08-29T17:58:00.000Z",
"markedUnread": false,
"isMuted": false,
"isFavorite": true,
"members": [
{
"employeeId": "emp_12ab",
"name": "Joseph Hall",
"role": "ADMIN",
"isExternal": false,
"isDeactivated": false
},
{
"employeeId": "emp_44f1",
"name": "Ada Reyes",
"role": "MEMBER",
"isExternal": false,
"isDeactivated": false
}
],
"latestMessage": {
"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",
"unreadReplyCount": 1,
"editedAt": null,
"deletedAt": null,
"pinnedAt": null,
"attachments": [],
"reactions": [],
"mentions": [
{
"employeeId": "emp_44f1"
}
],
"createdAt": "2026-08-29T18:10:00.000Z",
"preview": "Deploying the billing export now"
}
}
}
}{
"message": "You are not a member of this conversation."
}{
"message": "Conversation not found."
}In the console
The same thing done by hand, for anyone comparing the API against the screen they already use.