Reference

Chats Beta

On this page

A chat is a private conversation between named people across Slack and Microsoft Teams. Conclude creates a private Slack channel and a Microsoft Teams group chat, and syncs them. The requests on this page list, start, change and close chats.

A chat within your organization has a channel in your Slack workspace and one in your Microsoft Teams tenant. A chat with people of another organization runs over a Bridge. It has a channel in each organization, and the API shows only yours. Cross-platform chats describes how chats work in Slack and Microsoft Teams.

Who can use chats

Reading needs the scope chats:read. Every change needs chats:readwrite.

Only a chat’s members can see it. The requests on this page act for the person the token acts for:

  • A key that acts as you reaches your chats
  • A key that acts as Conclude, with a subject, reaches the subject’s chats
  • A key that acts as Conclude, without a subject, reads every chat with a channel in your organization. It can also start chats between the people it names. To change, check or delete a chat, it needs a subject. Without one, Conclude answers subject_required
  • For anyone else who is not a member, a chat doesn’t exist. Conclude answers not_found

Starting, changing and deleting a chat within your organization needs the Create chats permission from Admin console > Users and access > Roles & permissions . For a key that acts as Conclude, the scope chats:readwrite stands in for it.

A chat with another organization uses the bridge’s Chat access list instead of the Create chats permission. Everyone in the chat must be on that list, including the person the token acts for. Each organization manages its own list, so no scope can replace it. Any member of the chat can close it.

The chat object

{
  "id": "Y-7f9h1j3l",
  "topic": "Laptop refresh",
  "autoName": true,
  "status": "ok",
  "lastActivity": "2026-11-05T09:12:44Z",
  "myChannelID": "C-6e8g0i2k",
  "channels": [
    {
      "id": "C-6e8g0i2k",
      "name": "chat_ana_ben",
      "platform": "slack",
      "sysID": "C07ABCDEF12",
      "workspace": {
        "id": "T-4c6e8g0i",
        "name": "Example",
        "sysID": "T04ABCDEF12"
      },
      "url": "slack://channel?team=T04ABCDEF12&id=C07ABCDEF12"
    },
    {
      "id": "C-9i1k3m5o",
      "name": "Chat between Ana and Ben",
      "platform": "teams",
      "sysID": "19:a1b2c3d4@thread.v2",
      "workspace": {
        "id": "T-8h0j2l4n",
        "name": "Example",
        "sysID": "8f0e2d4c-6b8a-4c2e-9f1d-3b5a7c9e1f20"
      },
      "url": "https://teams.microsoft.com/l/chat/19:a1b2c3d4@thread.v2"
    }
  ],
  "members": [
    {
      "id": "U-2b4d6f8h",
      "mention": "Ana",
      "name": "Ana Silva",
      "email": "ana@example.com",
      "avatar": "https://avatars.example.com/ana.png",
      "orgID": "O-2a4c6e8g"
    },
    {
      "id": "U-3b5d7f9h",
      "mention": "Ben",
      "name": "Ben Okafor",
      "email": "ben@example.com",
      "orgID": "O-2a4c6e8g"
    }
  ]
}
FieldTypeDescription
idstringThe chat’s ID. The paths below take it as {chat}.
topicstringThe chat’s topic. It is empty when the chat has none.
autoNamebooleantrue when Conclude names the channels after the members. Adding or removing members then renames them.
statusstringThe chat’s health. See Status.
lastActivitytimeWhen a message last synced, to the minute. Left out until the first message.
myChannelIDstringThe chat’s channel that the person the token acts for is in. Left out for a key that acts as Conclude without a subject.
bridgeobjectOnly on a chat with another organization. The bridge’s id, and the other organization as partner, with its id and name.
channelsarrayYour organization’s channels of the chat, as chat channel objects.
membersarrayThe chat’s members, as user objects.

The chat channel object

A chat’s channel is a private Slack channel or a Microsoft Teams group chat.

FieldTypeDescription
idstringThe channel’s Conclude ID.
namestringThe channel’s name.
platformstringslack or teams.
sysIDstringThe Slack channel ID or the Microsoft Teams chat ID.
workspaceobjectThe Slack workspace or Microsoft Teams tenant the channel is in, with its id, name and sysID.
urlstringA link that opens the channel in Slack or Microsoft Teams. A Slack link opens the Slack app.

The user object

FieldTypeDescription
idstringThe person’s Conclude user ID.
mentionstringThe name people use to mention the person in Slack or Microsoft Teams.
namestringThe person’s full name. It is the same as mention when Conclude doesn’t know the full name.
emailstringThe person’s email address, when Conclude knows it.
avatarstringThe URL of the person’s picture, when there is one.
orgIDstringThe person’s organization. In a chat with another organization, it tells the two sides apart.

Status

StatusMeaning
okThe chat syncs.
pausedConclude stopped syncing one of the chat’s channels after it stayed broken. The channel syncs again once Conclude finds it healthy.

Any other value is the status of the first broken channel, such as noAuth or deactivated. The Connections page says what to do about each.

List chats

GET /v1/chats · scope chats:read

Returns a page of chats, newest first by when they were created. It includes chats with other organizations, and leaves out chats on a bridge that an admin has paused.

ParameterDescription
bridgeOptional. A bridge ID returns only the chats over that bridge. none returns only the chats within your organization.
limitThe number of chats on a page, from 1 to 500. The default is 50. A larger value returns 500.
positionThe nextPosition from the previous page.
curl -G https://api.conclude.io/v1/chats \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  --data-urlencode "bridge=none"
FieldTypeDescription
chatsarrayThe chat objects on this page.
nextPositionstringThe position of the next page. It is empty on the last page.

To read the next page, send the same request with position set to nextPosition. URL-encode the value.

StatusCodeWhen
400invalid_requestlimit is not a positive number, or position is not one Conclude returned. param names the parameter.
404not_foundbridge is not a bridge of your organization. param is bridge.

Get a chat

GET /v1/chats/{chat} · scope chats:read

Returns one chat object.

curl https://api.conclude.io/v1/chats/Y-7f9h1j3l -H "Authorization: Bearer $ACCESS_TOKEN"
StatusCodeWhen
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member. Or the chat’s bridge is paused.

Start a chat

POST /v1/chats · scope chats:readwrite

Starts a chat between the person the token acts for and the people you name. Conclude creates a private Slack channel and a Microsoft Teams group chat and adds everyone to them. The audit log records connect.chat.created.

A key that acts as Conclude, without a subject, starts a chat between the people you name. Name at least two, and at least one from your organization. The first of them from your organization counts as the person who started the chat. The audit log names Conclude.

FieldTypeRequiredDescription
membersarray of stringsYesThe user IDs of the people to chat with. GET /v1/findUser finds them in your organization.
bridgestringNoThe ID of the bridge to start the chat over, with people of another organization. See Chats with another organization.
topicstringNoThe chat’s topic.
namestringNoThe name of the channels. Without it, Conclude names them after the members.
curl https://api.conclude.io/v1/chats \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"members": ["U-3b5d7f9h"], "topic": "Laptop refresh"}'

The response has these fields:

FieldTypeDescription
chatobjectThe new chat object.
skippedMembersarrayUser objects of the people Conclude didn’t add, because they have no account in the chat’s workspaces. Left out when Conclude added everyone. A chat with another organization never has it, so compare the chat’s members with the people you named.
warningsarray of stringsMessages for people to read, such as how many members Conclude skipped. Left out when there are none.

Slack and Microsoft Teams can take a few seconds to add everyone. Check the members to find people they didn’t add.

Chats with another organization

To chat with people of another organization, name your bridge with that organization in bridge. GET /v1/bridges lists your bridges, and GET /v1/bridges/{bridge}/chatUsers lists the people you can name. Everyone must have Chat access on the bridge, and at least one of them must be from the other organization. A key that acts as Conclude, without a subject, names at least two people. The first of them on your organization’s side of the Chat access list counts as the person who started the chat. The audit log records bridge.chat.created instead.

curl https://api.conclude.io/v1/chats \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"members": ["U-5e7g9i1k"], "bridge": "B-1a3c5e7g", "topic": "Renewal"}'

Without bridge, everyone you name must be a user in your organization, even someone who is on a bridge’s Chat access list.

StatusCodeWhen
400invalid_requestmembers is empty, or a member is not a user in your organization. param names the member, as in members.1. With bridge, no member is from the other organization. The person the token acts for has no account to start the chat from. A key that acts as Conclude, without a subject, named fewer than two members.
400chat_member_not_allowedMicrosoft Teams wouldn’t add a member, such as a guest or an account without a Teams license. Or a member doesn’t have Chat access on the bridge. Or a key that acts as Conclude, without a subject, named no one from your side of the bridge’s Chat access list. param names the member when Conclude knows which one.
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403bridge_chat_not_allowedThe person the token acts for doesn’t have Chat access on the bridge.
403plan_limitYour organization’s plan doesn’t include chats. With bridge, neither organization’s plan includes bridges. param is chats or bridge.
404not_foundbridge is not a bridge of your organization. param is bridge.
409chat_needs_two_workspacesYour organization doesn’t have two workspaces to chat across, such as a Slack workspace and a Microsoft Teams tenant.
409teams_license_missingNone of the Microsoft Teams accounts that Conclude can use has a Teams license.
409teams_sign_in_requiredMicrosoft Teams needs a member, or the integration account, to be signed in to Conclude.
409bridge_not_activeAn admin has paused the bridge.
409conflictConclude couldn’t create the chat’s channel in one of the organizations. A member from that organization must sign in to Conclude.

Change a chat

PATCH /v1/chats/{chat} · scope chats:readwrite

Changes the chat’s topic, the name of its channels and its members, as one change. Slack and Microsoft Teams rename the channels at most once. A field you leave out stays as it is. Changes to one chat’s members run one at a time, so a request waits while another one changes the chat.

FieldTypeRequiredDescription
topicstringNoThe new topic. An empty string removes it.
namestringNoThe new name of the channels. An empty string names them after the members again.
addMembersarray of stringsNoThe user IDs of people from your organization to add. People who are already members stay as they are.
removeMembersarray of stringsNoThe user IDs of members to remove. The person the token acts for can’t remove themselves.
curl -X PATCH https://api.conclude.io/v1/chats/Y-7f9h1j3l \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"topic": "Laptop refresh, phase 2", "addMembers": ["U-4c6e8g0i"], "removeMembers": ["U-3b5d7f9h"]}'

The response has the changed chat object as chat, and the people Conclude didn’t add as skippedMembers, as when you start a chat. When autoName is true and the members changed, Conclude renames the channels after them. The audit log records connect.chat.updated when people joined or left, or the channels got a new name.

StatusCodeWhen
400invalid_requestA person in addMembers is not a user in your organization. A person in removeMembers is not a member, or is the person the token acts for. param names the person, as in removeMembers.0.
400chat_member_not_allowedMicrosoft Teams wouldn’t add a member, such as a guest or an account without a Teams license, to a chat channel Conclude creates for the change.
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403subject_requiredA key that acts as Conclude sent no subject.
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member.
409bridge_chat_unsupportedThe chat is with another organization. Such a chat can only be read and closed.
409conflictAnother change to the chat’s members is still running after a minute. Try again.
500internal_errorMicrosoft Teams wouldn’t add a member to the chat’s existing channel. Other changes may already have gone through, so check the members.

Add members

POST /v1/chats/{chat}/members · scope chats:readwrite

Adds people from your organization to the chat. People who are already members stay as they are. To add and remove people in one change, change the chat instead. Changes to one chat’s members run one at a time, so a request waits while another one changes the chat.

FieldTypeRequiredDescription
membersarray of stringsYesThe user IDs of the people to add.
curl https://api.conclude.io/v1/chats/Y-7f9h1j3l/members \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"members": ["U-4c6e8g0i"]}'

The response has the changed chat object as chat, and the people Conclude didn’t add as skippedMembers, as when you start a chat. When autoName is true, Conclude renames the channels after the new members. The audit log records connect.chat.updated.

StatusCodeWhen
400invalid_requestmembers is empty, or a member is not a user in your organization. param names the member, as in members.0.
400chat_member_not_allowedMicrosoft Teams wouldn’t add a member, such as a guest or an account without a Teams license, to a chat channel Conclude creates for the change.
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403subject_requiredA key that acts as Conclude sent no subject.
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member.
409bridge_chat_unsupportedThe chat is with another organization.
409conflictAnother change to the chat’s members is still running after a minute. Try again.
500internal_errorMicrosoft Teams wouldn’t add a member to the chat’s existing channel. Other changes may already have gone through, so check the members.

Remove a member

DELETE /v1/chats/{chat}/members/{user} · scope chats:readwrite

Removes a person from the chat. {user} is their user ID. The person the token acts for can’t remove themselves. Another member can, or they can delete the chat.

curl -X DELETE https://api.conclude.io/v1/chats/Y-7f9h1j3l/members/U-4c6e8g0i \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The response has the changed chat object as chat. When autoName is true, Conclude renames the channels after the remaining members. The audit log records connect.chat.updated.

StatusCodeWhen
400invalid_request{user} is the person the token acts for. param is user.
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403subject_requiredA key that acts as Conclude sent no subject.
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member. Or {user} is not a member.
409bridge_chat_unsupportedThe chat is with another organization.
409conflictAnother change to the chat’s members is still running after a minute. Try again.

Check members

POST /v1/chats/{chat}/verify · scope chats:readwrite

Reads the members of each channel from Slack and Microsoft Teams again, and returns the members who are missing from a channel. The request has no body.

curl -X POST https://api.conclude.io/v1/chats/Y-7f9h1j3l/verify \
  -H "Authorization: Bearer $ACCESS_TOKEN"
{
  "missingMembers": []
}

missingMembers is a list of user objects. A member is missing when they are in the chat on one platform, but not in the channel on the other.

  • Right after you start or change a chat, Slack or Microsoft Teams may still be adding someone. Wait a few seconds and check again
  • To try again, add the person once more. Conclude then invites everyone who is missing from a channel
  • If someone stays missing, Microsoft Teams won’t add them. That happens to guests and to accounts without a Teams license. Remove them from the chat, or leave them as they are
StatusCodeWhen
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403subject_requiredA key that acts as Conclude sent no subject.
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member.
409bridge_chat_unsupportedThe chat is with another organization.

Delete a chat

DELETE /v1/chats/{chat} · scope chats:readwrite

Closes the chat and stops syncing it. Conclude archives the Slack channel and deletes the Microsoft Teams group chat. Microsoft Teams can’t archive a group chat, so the members lose its history in Microsoft Teams. The audit log records connect.chat.deleted.

On a chat with another organization, Conclude closes the channels of both organizations. Any member can do this, without the Create chats permission. The audit log records bridge.chat.closed.

curl -X DELETE https://api.conclude.io/v1/chats/Y-7f9h1j3l -H "Authorization: Bearer $ACCESS_TOKEN"

The response can have warnings, a list of messages for people to read. They name what Conclude couldn’t clean up, such as a channel it couldn’t archive.

StatusCodeWhen
403forbiddenThe person the token acts for doesn’t have the Create chats permission.
403subject_requiredA key that acts as Conclude sent no subject.
404not_foundThe chat doesn’t exist, or the person the token acts for is not a member.