Go to Slack

Conversations API

Public channels, private channels, DMs... They are all conversations!

The new Slack Conversations API provides your app with a unified interface to work with all the channel-like things encountered in Slack; public channels, private channels, direct messages, group direct messages, and our newest channel type, Shared Channels.

Use this API family to review history, create or archive channels, invite team members, set conversation topic and purpose, and more — regardless of the type of the channel your app is working with.

While we're introducing this family of methods to work with the Shared Channels due to its unique channel privacy model, the Conversations API can be used by all apps equipped with the appropriate OAuth scopes already required by existing methods.

Use the Conversations API for anything channel-like

If it walks like a duck, quacks like a duck, and swims like a duck — it's probably a duck!

If it works like a channel, has messages like a channel, and is experienced like a channel... it's a channel conversation!!!

Several ducks are typing
"Several ducks are typing..."

Before the Conversations API, you needed to use different methods from multiple "family trees" to achieve the same thing depending on the type of the channel you were working with.

For example, to list direct messages you must request ims.list or for public channels channels.list. Many different objects and shapes to juggle that at their core all represented the same type of timeline message container.

In the new model, just use conversations.* to access anything channel-like. For example, the conversation.list method returns information on any of public, private, or direct message channels, when accessed with the appropriate permission scopes.

Example: Getting a list of channels:

Channel Type Previously used method New method you should use
Public channels.list conversations.list
Private groups.list conversations.list
DM im.list conversations.list
Group DM mpim.list conversations.list

Conversations API methods

Method & Description Description
conversations.archive
Archives a conversation.
Archives a conversation.
conversations.close
Closes a direct message or multi-person direct message.
Closes a direct message or multi-person direct message.
conversations.create
Initiates a public or private channel-based conversation
Initiates a public or private channel-based conversation
conversations.history
Fetches a conversation's history of messages and events.
Fetches a conversation's history of messages and events.
conversations.info
Retrieve information about a conversation.
Retrieve information about a conversation.
conversations.invite
Invites users to a channel.
Invites users to a channel.
conversations.join
Joins an existing conversation.
Joins an existing conversation.
conversations.kick
Removes a user from a conversation.
Removes a user from a conversation.
conversations.leave
Leaves a conversation.
Leaves a conversation.
conversations.list
Lists all channels in a Slack team.
Lists all channels in a Slack team.
conversations.members
Retrieve members of a conversation.
Retrieve members of a conversation.
conversations.open
Opens or resumes a direct message or multi-person direct message.
Opens or resumes a direct message or multi-person direct message.
conversations.rename
Renames a conversation.
Renames a conversation.
conversations.replies
Retrieve a thread of messages posted to a conversation
Retrieve a thread of messages posted to a conversation
conversations.setPurpose
Sets the purpose for a conversation.
Sets the purpose for a conversation.
conversations.setTopic
Sets the topic for a conversation.
Sets the topic for a conversation.
conversations.unarchive
Reverses conversation archival.
Reverses conversation archival.

Working with Shared Channels

Shared Channels is ready for development during the beta.

You can build support for shared channels today. The API is feature complete and we don't anticipate any major changes before shared channels becomes widely available.

Each channel has a unique-to-the-team ID that beginning with a single letter prefix, either C, G, or D. When a channel is shared across teams (see Developing for Shared Channels), the prefix of the channel ID may be changed, e.g. a private channel with ID, G0987654321 may become C0987654321.

Private channels will have an is_private:true flag on them in API responses and events. This is one of reasons you should use the conversations.* instead of the existing API methods! You cannot rely on a private shared channel's unique ID remaining constant during its entire lifetime as a result.

The channel type object tells you additional channel info. If the channel is shared, is_shared is set true. If it is a private channel or a group DM channel, the properties, is_private or is_mpim is set true, respectively.

The response to conversations.list including a shared channel returns the following output:

{
    "ok": true,
    "channels": [
        {
            "id": "C0AMV1W3T",
            "name": "shared-project-01",
            "is_channel": true,
            "created": 1494292130,
            "creator": "U07QCR6A4",
            "is_archived": false,
            "is_general": false,
            "name_normalized": "shared-project-01",
            "is_shared": true,
            "is_org_shared": false,
            "is_member": false,
            "is_private": false,
            "is_mpim": false,
            "members": [
                "U07QCR6A4",
                "U0A53A05N"...
            ],
            "topic": {
                "value": "",
                "creator": "",
                "last_set": 0
            },
            "purpose": {
                "value": "",
                "creator": "",
                "last_set": 0
            },
            "previous_names": [],
            "num_members": 27
        },
        ...
    ]
}

The conversational booleans

Some of the most important fields in conversation objects are the booleans indicating what kind of conversation/channel it is and how private it is.

Here's a legend.

  • is_archived indicates a conversation is archived. Frozen in time.
  • is_channel indicates whether a conversation is a public channel. Everything said in a public channel can be read by anyone else belonging to a workspace. is_private will be false. Check both just to be sure, why not?
  • is_ext_shared represents this conversation as being part of a Shared Channel with a remote organization. Your app should make sure the data it shares in such a channel is appropriate for both workspaces. is_shared will also be true.
  • is_general means the channel is the workspace's "general" discussion channel (even if it's not named #general but it might be anyway). That might be important to your app because almost every user is a member.
  • is_group means the channel is a private channel. is_private will also be true. Check yourself before you wreck yourself.
  • is_im means the conversation is a direct message between two distinguished individuals or a user and a bot. Yes, it's an is_private conversation.
  • is_member indicates the user or bot user or Slack app associated with the token making the API call is itself a member of the conversation.
  • is_mpim represents an unnamed private conversation between multiple users. It's an is_private kind of thing.
  • is_org_shared explains whether this shared channel is shared between Enterprise Grid workspaces within the same organization. It's a little different from (externally) Shared Channels. Yet, is_shared will be true.
  • is_pending_ext_shared is intriguing. It means the conversation is ready to become an is_ext_shared channel but isn't quite ready yet and needs some kind of approval or sign off. Best to treat it as if it were a shared channel, even if it traverses only one workspace.
  • is_private means the conversation is privileged between two or more members. Meet their privacy expectations.
  • is_read_only means the conversation can't be written to by typical users. Admins may have the ability.
  • is_shared means the conversation is in some way shared between multiple workspaces. Look for is_ext_shared and is_org_shared to learn which kind it is, and if that matters, act accordingly. Have we mentioned how great is_private is yet?

Conversation membership

Discover who is party to a conversation with conversations.members, a paginated method allowing you to safely navigate through very large (or tiny) collections of users.

Permission Scopes

All Conversations API endpoints accept multiple scopes and filter access to channels based on the provided token's scope. If you have a scope that allowed you to use a classic decomposed conversation method, that scope will work with the Conversations API equivalent.

For instance, conversations.list accepts channels:read, groups:read, mpim:read, and im:read.

If you only have channels:read, conversations.list will only contain public channels and all the related methods will only deal with public channels. If you have both channels:read and im:read, then it will only have public channels and DMs, and so on.

Pagination

The Conversations API uses our cursor-based pagination model, improving the performance of requests over large sets of data. You could even walk through a list of channels 1-by-1 if you fancy.

Just set a limit on your first request, include the next_cursor found in response_metadata in the response as the cursor parameter in your next request and you're paginating with ease on the conversational trapeze.

Unlike older methods, the Conversations API is paginated by default.

Inconsistent page size is a feature, not a bug

Please keep in mind that it's possible to receive fewer results than your specified limit, even when there are additional results to retrieve. Maybe you'll even receive 0 results but still have a next_cursor with 4 more waiting in the wings.

When looking up MPIMs using the conversations.list, you are likely to get far fewer results than requested number with a next_cursor value, although next_cursor will continue to indicate when more results await. e.g. When requesting 100 MPIMs, it may return only 5.

Read more about the pagination model.

Known issues

🚧 Channel IDs can become unstable in certain situations

There are a few circumstances channel IDs might change within a workspace. If you can operate without depending on their stability, you'll be well-prepared for unfortunate hijinks.

In the future, we'll mitigate this unexpected transition with appropriate Events API events or other solutions.

In the meantime, be aware this might happen and use conversations.list regularly to monitor change for known #channel names if ID stability is important to you.

🚧 Shared private channels aren't ready yet

Shared private channels are still under construction. You will see some glitches in the response data when a method, like conversations.open is called.

🚧 MPIM events tell little lies about channel types

In a multiparty direct message channel ("MPIM") with a foreign user, events like member_joined_channel and member_left_channel may dispatch an incorrect value for channel_type.

🚧 IM Object format is not yet consistent

IM formats may differ from other channel objects for a while. We're working towards making all objects the same format. You may notice members lists that aren't meant to be there.

These are almost all cleared up!

🚧 Unsharing channels

When a channel becomes unshared, conversations.history access for the channel may become unreliable.

Stay tuned for future updates!


Start using the conversations.* method for all types of channels. Instead of reaching for channels.list or ims.list or whoositswhatsits.list, use conversations.list.

We don't plan to deprecate the old ways any time soon, but we're certain this new Conversations API model is the way forward. Journey with us.

Several ducks are typing Several ducks are typing Several ducks are typing