Skip to main content

Slack Enterprise Collection

Slack Enterprise Collection Integration with Onna

Overview

This guide explains how to set up and interact with a Slack Enterprise (eslack) collection through the Onna Platform API. You'll learn how to create a workspace, wallet, and collection, authorize access to Slack via OAuth2, list the users, teams, and channels available in the Slack organization, configure sync filters to control exactly which custodians and conversations are synchronized, start the sync, and clean up your environment afterward.

Slack sync filters support several content types that can be combined:

  • Conversations - public channels (public), private channels (private), direct messages (im), and group direct messages (mpim).
  • Custodians - per-user conversation selection, including controls for externally shared (Slack Connect) and multi-workspace shared channels.
  • Root files - Slack Canvases (canvas) and Lists (list) collected alongside conversations.

For a full reference of every sync filter field, see the Sync Filters Configuration Guide.

Create a workspace

A workspace is the main container for your project in Onna. Create one with a POST request.

curl --location --request POST 'https://api.onna.com/v1/workspaces' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "My New Workspace",
"description": "This is a workspace for organizing Slack data in Onna."
}'

Where:

  • name is the name of the workspace.
  • description is a brief description of the workspace's purpose.

A successful response (201) will return:

{
"onna_id": "<WORKSPACE_ID>"
}

Create a Slack Wallet

Slack credentials are stored in a wallet that the collection references. Create an empty wallet first; the OAuth pairing step later populates it with the access token.

curl --location --request POST 'https://api.onna.com/v1/wallet' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Slack Enterprise Collection Wallet",
"credential_type_name": "SlackEDatasource"
}'

Where:

  • name is a label for the wallet.
  • credential_type_name is the credential type. For Slack Enterprise, use SlackEDatasource.

A successful response (201) will return:

{
"onna_id": "<WALLET_ID>"
}

Create a Slack Collection

Next, create a Slack collection within the workspace you created. The collection is the container for the users and content you will sync from Slack.

curl --location --request POST 'https://api.onna.com/v1/collections' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "My Slack Enterprise Collection",
"onna_parent_id": "<WORKSPACE_ID>",
"type": "eslack",
"credential_id": "<WALLET_ID>"
}'

Where:

  • name is the name of the collection.
  • onna_parent_id is the ID of the workspace that this collection will belong to.
  • type is the type of collection being created. For Slack Enterprise, the type is eslack.
  • credential_id is the ID of the wallet you created for the Slack service.

A successful response (201) will return:

{
"onna_id": "<COLLECTION_ID>",
"type": "eslack"
}
Actionable Tips: While creating collections, consider adding metadata that might be required later for reporting or analysis.

You might also want to implement a naming convention (like Collection-{WorkspaceName}-Slack) for better organization.

Initiate OAuth2 Flow to Get an Authorization Code

To authorize access to Slack, initiate the OAuth2 flow. It will return an authorization URL. Open this URL in your browser to log in and grant the application access to Slack.

curl --location --request GET 'https://api.onna.com/v1/collections/authorization_url/eslack?redirect_to=http%3A%2F%2Flocalhost%3A9000%2Fcallback' \
--header 'Authorization: Bearer <token>'

Once you've authorized, you'll be redirected to the provided redirect_to URL with an authorization code.

Use a temporary redirect URI during development (like http://localhost:9000/callback) for easier testing. Be sure to change this to a production-ready URL before going live.

Pair the Authorization Code with the Collection (Token Exchange)

After successful authorization, exchange the authorization code for an access token bound to the collection. The token exchange is performed by the platform.

curl --location --request POST 'https://api.onna.com/v1/collections/<COLLECTION_ID>/pair_credentials?auth_code=<AUTH_CODE>' \
--header 'Authorization: Bearer <token>'

Where:

  • auth_code is the authorization code you received during the authorization process.

A successful response returns 204 No Content.

Alternatively, you can pair the authorization code with the wallet instead of the collection by sending the same request to

POST /wallet/<WALLET_ID>/pair_credentials?auth_code=<AUTH_CODE>. Pairing at the collection level (shown above) is the typical approach.

Retrieve Users, Teams, and Channels

Before configuring sync filters, retrieve the entities available in the authorized Slack organization. You will use the returned IDs when building the sync_filters object.

Users

Send a GET request to the collection's /users endpoint to list the custodians (users) available in the organization.

curl --location --request GET 'https://api.onna.com/v1/collections/<COLLECTION_ID>/users?limit=10' \
--header 'Authorization: Bearer <token>'

The endpoint accepts two optional query parameters:

  • limit is the number of users to return per page.
  • offset is the pagination cursor. To fetch the next page, pass the value from the previous response's offset field. Omit it for the first page.

Example user response:

{
"users": [
{
"id": "U1234567890",
"name": "lisa.simpson",
"profile": {
"real_name": "Lisa Simpson",
"display_name": "Lisa",
"email": "lisa@onnaqa.com"
},
"teams": ["T1234567890"],
"is_bot": false,
"deleted": false
}
],
"offset": "U0987654321"
}

Where:

  • id is the unique Slack user ID. Use this value as a custodian id when configuring sync filters.
  • name is the user's Slack username.
  • profile contains the user's real_name, display_name, and email.
  • teams is the list of team IDs the user belongs to.
  • is_bot indicates whether the user is a bot account.
  • deleted indicates whether the user has been deactivated.
  • offset is the cursor for the next page of results, or null when there are no more pages. To page through all users, pass this value as the offset query parameter on the next request and repeat until it is null.

Teams

Send a GET request to the collection's /teams endpoint to list the teams (workspaces within the Enterprise Grid).

curl --location --request GET 'https://api.onna.com/v1/collections/<COLLECTION_ID>/teams' \
--header 'Authorization: Bearer <token>'

Example team response (a JSON array):

[
{
"id": "T1234567890",
"name": "Engineering",
"description": ""
},
{
"id": "T0987654321",
"name": "Sales",
"description": ""
}
]

Where:

  • id is the Slack team ID. Use this value in the teams filter and as the team_id of a conversation.
  • name is the team's display name.
  • description is the team's description (may be an empty string).

Channels

Send a GET request to the collection's /channels endpoint to list the conversations available for a given user and team. This is useful for identifying channel IDs when configuring conversation-level filters.

curl --location --request GET 'https://api.onna.com/v1/collections/<COLLECTION_ID>/channels?user=<USER_ID>&
teams=<TEAM_ID>&limit=10&include_workspace_shared_all=true&include_workspace_shared_selected=false&types=public&types=private' \
--header 'Authorization: Bearer <token>'

Where:

  • user is the Slack user ID whose channels you want to list.
  • teams is the Slack team ID to scope the channels to.
  • limit is the number of channels to return.
  • types selects which conversation types to return. Repeat the parameter for each type (public, private, im, mpim).
  • include_workspace_shared_all includes channels shared across all workspaces.
  • include_workspace_shared_selected includes channels shared only with selected workspaces (slower to load).

Example channel response:

{
"results": [
{
"id": "C1234567890",
"type": "public",
"name": "general",
"team_id": "T1234567890",
"is_archived": false,
"is_shared": false,
"is_org_shared": false,
"is_ext_shared": false,
"shared_with": [],
"topic": {
"text": "Company-wide announcements and work-based matters",
"set_by": "U1234567890",
"date_set": 1513810069
},
"purpose": {
"text": "This channel is for workspace-wide communication and announcements.",
"set_by": "U1234567890",
"date_set": 1513810069
},
"is_file": false,
"is_file_channel": false
}
],
"offset": "C0987654321"
}

Where:

  • id is the Slack channel ID. Use this value as a conversation id when configuring sync filters.
  • type is the conversation type (public, private, im, or mpim).
  • name is the channel's display name.
  • team_id is the team the channel belongs to. Pair it with the channel id in the conversations.selected array.
  • is_shared, is_org_shared, and is_ext_shared indicate how the channel is shared (across workspaces, across the org, or externally via Slack Connect).
  • topic and purpose contain the channel's topic and purpose text.
  • offset is the cursor for the next page of channels, or null when there are no more pages.

Configure Sync Filters

Slack Enterprise collections always collect per custodian: you choose the users to sync, and for each user the conversations to include. The sync_filters object must use this custodian shape, so custodians is required. A channel-first (regular) payload, or one missing custodians, is rejected with 422 Unprocessable Entity.

Sync filters control which content is pulled into the collection, using the following top-level keys inside the sync_filters object:

  • custodians - required. The users to sync, and for each user the conversations to include along with external and multi-workspace sharing controls. List each user explicitly in selected — there is no "all custodians" shortcut (see the note below).
  • types - selects which conversation types to sync (public, private, im, mpim).
  • teams - selects which teams to include or exclude.
  • collect_root_files - optionally collects Slack Canvases and Lists.

Update the collection with the selected configuration by sending a PATCH request.

Sync specific teams, users, and conversations

Set all_selected to false under teams and custodians, list the teams and users to include, and select individual conversations per user. Each conversation entry pairs a channel id with its team_id.

curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"types": {
"selected": [
{ "id": "public" },
{ "id": "private" },
{ "id": "im" },
{ "id": "mpim" }
]
},
"teams": {
"all_selected": false,
"sync_future": false,
"selected": [{ "id": "T1234567890" }]
},
"custodians": {
"all_selected": false,
"sync_future": false,
"selected": [
{
"id": "U1234567890",
"conversations": {
"all_selected": false,
"sync_future": false,
"selected": [
{ "id": "C1234567890", "team_id": "T1234567890" }
],
"check_workspace_sharing": true,
"check_external_sharing": true,
"only_ext_shared": false
}
}
]
}
}
}'

Sync all teams for selected users

Custodian collection requires listing each user you want to sync in custodians.selected; there is no "all custodians" option, and setting custodians.all_selected to true with an empty selected array collects nothing. To collect broadly, set teams.all_selected to true (every team) and give each custodian a conversations object with all_selected set to true (every conversation that user is in).

curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"types": {
"selected": [
{ "id": "public" },
{ "id": "private" },
{ "id": "im" },
{ "id": "mpim" }
]
},
"teams": {
"all_selected": true,
"sync_future": true,
"selected": [],
"excluded": []
},
"custodians": {
"all_selected": false,
"sync_future": false,
"selected": [
{
"id": "U1234567890",
"conversations": { "all_selected": true, "sync_future": true }
},
{
"id": "U0987654321",
"conversations": { "all_selected": true, "sync_future": true }
}
]
}
}
}'
all_selected behaves differently at each level. On custodians it is not honored — always list each user

in selected. On a custodian's conversations it is honored: set it to true to collect every conversation that user belongs to (as shown above), or false to collect only the conversations you list. The collection never discovers users on its own, so append an entry to custodians.selected for every user you need.

Collect Canvases and Lists

To collect Slack Canvases and Lists alongside conversations, add a collect_root_files object. List each file type to collect in selected, with all_selected set to true on each entry. Root files are collected for the custodians you list in custodians.selected, so include the users whose Canvases and Lists you want.

curl --location --request PATCH 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"sync_status": "pending",
"sync_filters": {
"types": {
"selected": [{ "id": "public" }]
},
"teams": {
"all_selected": true,
"sync_future": true,
"selected": [],
"excluded": []
},
"custodians": {
"all_selected": false,
"sync_future": false,
"selected": [
{
"id": "U1234567890",
"conversations": { "all_selected": true, "sync_future": true }
}
]
},
"collect_root_files": {
"all_selected": false,
"selected": [
{ "id": "canvas", "all_selected": true },
{ "id": "list", "all_selected": true }
]
}
}
}'

Filter fields

The top-level request fields are the same as any collection update:

FieldTypeDescription
sync_statusStringSync lifecycle state. Set to "pending" to queue a sync after filters are saved.
sync_filtersObjectSlack sync filter configuration (see below).
type_syncStringSync type. Supported values: "one", "arch", "auto".

The types object selects which conversation types are collected:

FieldTypeDescription
selectedArrayConversation types to sync. Supported values: { "id": "public" }, { "id": "private" }, { "id": "im" }, { "id": "mpim" }.

The teams object controls team selection:

FieldTypeDescription
all_selectedBooleanIf true, all teams in the organization are included. When false, only teams listed in selected are included.
sync_futureBooleanWhether to include teams added in the future.
selectedArrayTeams to include when all_selected is false. Each entry is { "id": "<team_id>" }.
excludedArrayTeams to exclude when all_selected is true. Each entry is { "id": "<team_id>" }.

The custodians object controls user selection and, per user, their conversations:

FieldTypeDescription
all_selectedBooleanRequired. Set to false for Slack Enterprise collections — users must be listed explicitly in selected. There is no "all users" expansion for custodians via the public API.
sync_futureBooleanWhether to include users added in the future.
selectedArrayRequired. The users to include. Each entry must contain a user id and a conversations object (see below).

Each entry in custodians.selected contains a conversations object that scopes the channels collected for that user:

FieldTypeDescription
all_selectedBooleanIf true, all of the user's conversations are included. When false, only conversations listed in selected are included.
sync_futureBooleanWhether to include conversations added in the future.
selectedArrayConversations to include when all_selected is false. Each entry is { "id": "<channel_id>", "team_id": "<team_id>" }.
excludedArrayConversations to exclude when all_selected is true. Each entry is { "id": "<channel_id>", "team_id": "<team_id>" }.
check_external_sharingBooleanIf true, include externally shared (Slack Connect) conversations. Set to false to skip them.
only_ext_sharedBooleanIf true, collect only externally shared conversations.
check_workspace_sharingBooleanIf true, include channels shared across multiple workspaces. Set to false to skip them.

The optional collect_root_files object enables collection of Slack Canvases and Lists:

FieldTypeDescription
all_selectedBooleanWhether to collect all root file types.
selectedArraySpecific file types to collect. Each entry is { "id": "canvas", "all_selected": true } or { "id": "list", "all_selected": true }.

A successful PATCH returns 204 No Content, indicating the filter configuration was saved.

Update Existing Filters

To change an existing filter configuration (for example, to add a custodian or include additional conversations), issue another PATCH to the same collection endpoint with the full updated sync_filters object. The new value replaces the previous one.

Always send the complete sync_filters object on update. Fields that are omitted are treated as removed, not merged with the previous value.

Start the Sync

Once the filters are saved, initiate the sync process.

curl --location --request POST 'https://api.onna.com/v1/collections/<COLLECTION_ID>/start' \
--header 'Authorization: Bearer <token>'

A successful response (HTTP status code 200) indicates that the sync process has begun. Only the teams, custodians, and conversations allowed by the configured filters are pulled into the collection.

Simulate Token Expiry and Refresh the Token

If the access token expires, you can refresh it by using the refresh token.

curl --location --request POST 'https://api.onna.com/v1/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'refresh_token=<refresh_token>'

This will return a new access_token and refresh_token.

{
"access_token": "<new_access_token>",
"token_type": "bearer",
"expires_in": 86399
}

Clean Up

Once you are done, you can clean up by deleting both the collection and the workspace.

curl --location --request DELETE 'https://api.onna.com/v1/collections/<COLLECTION_ID>' \
--header 'Authorization: Bearer <token>'
curl --location --request DELETE 'https://api.onna.com/v1/workspaces/<WORKSPACE_ID>' \
--header 'Authorization: Bearer <token>'

Note: Deleting a collection or workspace is permanent and cannot be undone.