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

TypeMembersNotes
directAt 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.
groupAny 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_ids lists 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.

Actionowneradminmember
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, role can be owner, admin or member. Any other value, or none, means member. 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_limit must 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:

FieldMeaning
roleowner, admin or member.
joined_atWhen they were added.
last_read_message_id, last_read_sequence, last_read_atTheir read cursor. See Read receipts & unread.
muted_untilSee 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_until field, 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 always null.
  • Transferring ownership, banning, or invite links.
  • Listing all conversations in the workspace from your backend. GET /v1/conversations lists the conversations of the user whose JWT you send, most recent first, up to 100.
Conversations & roles · Concepts · poolse docs