Conversations & roles
A conversation is where messages and calls happen. Every message belongs to exactly one conversation. Only its members can read it, post in it, see who is typing, or join its calls.
The endpoints are on Conversations. This page explains the rules behind them.
Types
| Type | Members | Notes |
|---|---|---|
direct | At most 2. | One per pair of users. Asking to create a direct conversation that already exists between the same two people returns the existing one. Adding a third member fails with direct_conversation_full. |
group | Any number, up to member_limit if you set one. | Can have a name and avatar_url. |
The type is fixed when the conversation is created. A direct chat cannot become a group.
name (up to 255 characters), avatar_url (up to 2048) and
custom_data (any JSON object) are optional for both types. poolse
does not use them itself. In a direct chat, apps usually show the
other person's name, resolved from member_external_ids through the
SDK's userResolver.
The direct-chat dedupe applies when an end user creates the conversation with exactly one other member. It is keyed on the two user ids, whichever of them asks.
Creating one and adding people
POST /v1/conversations with an end-user JWT:
- The caller becomes the conversation's owner.
member_external_idslists the other members by your ids. Unknown ids are created as users on the spot ("lazy provisioning"; at most 50 per hour per token).- Creating the conversation and adding the members happen in one step. If any member cannot be added, nothing is created.
Everyone who joins, the creator included, gets conversation:created
on their user channel. Your backend
gets conversation.created, then one member.added per other member
(webhook events).
Roles
Each member has one role: owner, admin or member.
| Action | owner | admin | member |
|---|---|---|---|
| Read messages, see members, join the realtime channel | ✓ | ✓ | ✓ |
| Send messages, react, mark read | ✓ | ✓ | ✓ |
| Place a call, start a room, join a call | ✓ | ✓ | ✓ |
| Edit own messages | ✓ | ✓ | ✓ |
| Delete own messages | ✓ | ✓ | ✓ |
| Delete anyone's message | ✓ | ✓ | — |
Update name, avatar, custom_data, settings, member_limit | ✓ | ✓ | — |
| Add members (with any role) | ✓ | ✓ | — |
| Remove other members | ✓ | ✓ | — |
| Leave (remove yourself) | ✓ | ✓ | ✓ |
Every conversation, member and message endpoint takes an end-user JWT, so these rules always apply. There is no API-key version that acts outside them.
Nobody can edit someone else's message, whatever their role.
Things to know about roles
- When adding members,
rolecan beowner,adminormember. Any other value, or none, meansmember. So an admin can add another owner. - An owner can leave like anyone else. poolse does not stop the last owner from leaving, so a group can be left without an owner or admin. After that, nobody can change its settings or add people through end-user calls.
member_limitmust be greater than 0. It is checked when members are added, not when you lower it, so a group can end up with more members than its limit. Two adds at the same moment can go one over.
Membership
A membership is the link between a user and a conversation. It holds:
| Field | Meaning |
|---|---|
role | owner, admin or member. |
joined_at | When they were added. |
last_read_message_id, last_read_sequence, last_read_at | Their read cursor. See Read receipts & unread. |
muted_until | See below. |
Adding someone who is already a member does nothing and is not an error.
A removed member no longer appears in the member list and can no
longer read, post or join calls. Their old messages stay. If their
app has the conversation's realtime channel open, the server closes it
at once (phx_close) and refuses a rejoin, so they stop receiving the
conversation immediately. No other event tells them about it.
Not available
These are not possible through the API today:
- Deleting a conversation. There is no delete endpoint. Remove the members instead, or stop showing it in your app.
- Changing a member's role. A role is set when the member is added. To change it, remove the member and add them again with the new role. This does not touch their messages, but it resets their read cursor.
- Muting a conversation. Memberships have a
muted_untilfield, and push notifications respect it: a muted member gets no chat notifications until that time, except for messages that mention them. But no endpoint sets it, so it is alwaysnull. - Transferring ownership, banning, or invite links.
- Listing all conversations in the workspace from your backend.
GET /v1/conversationslists the conversations of the user whose JWT you send, most recent first, up to 100.