> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Slack

**Authentication:** OAuth 2.0
**Categories:** Communication
## What you can do

Connect this agent connector to let your agent:

- **Send messages** — post to channels, DMs, and threads on behalf of your users
- **Read conversations** — retrieve channel history, thread replies, and direct messages
- **Manage channels** — create channels, invite members, and update channel settings
- **Look up users** — search for team members by name, email, or username
- **Upload files** — share files and attachments into any conversation

## Authentication

This connector uses **OAuth 2.0**. Scalekit acts as the OAuth client: it redirects your user to Slack, obtains an access token, and automatically refreshes it before it expires. Your agent code never handles tokens directly — you only pass a `connectionName` and a user `identifier`.

You supply your Slack **Connected App** credentials (Client ID + Secret) once per environment in the Scalekit dashboard.

Before calling this connector from your code, create the Slack connection in **AgentKit** > **Connections** and copy the exact **Connection name** from that connection into your code. The value in code must match the dashboard exactly.

## Set up the connector

Register your Scalekit environment with the Slack connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

1. ### Set up auth redirects

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **Slack** and click **Create**. Copy the redirect URI. It looks like `https:///sso/v1/oauth//callback`.
    
      > Image: Copy redirect URI from Scalekit dashboard

    - Log in to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**.

    - Select **From scratch**, enter an app name, and select your workspace.

    - Go to **OAuth & Permissions** and scroll to **Redirect URLs**.

    - Click **Add New Redirect URL** and paste the redirect URI from Scalekit. Click **Add**.

      > Image: Add redirect URL in Slack

2. ### Enable distribution

    - In your Slack app settings, go to **Manage Distribution**.

    - Under **Share Your App with Other Workspaces**, complete the checklist Slack shows for your app. This can include accepting Slack's distribution agreement, adding support and privacy URLs, and confirming that the redirect URL you added above is valid.

    - Click **Activate Public Distribution**.

      Slack app distribution must be active before users can authorize the app from external workspaces. If distribution is not active, OAuth can succeed in your development workspace but fail when a user tries to connect a second workspace.

      > Image: Enable Slack app distribution

    - From **Basic Information**, copy the **Client ID** and **Client Secret**.

3. ### Add credentials in Scalekit

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** and open the connection you created.

    Choose **Bot scope** for most agents, including agents that read channel history or send messages as your Slack app. Bot scope makes the agent act as the Slack app or bot; use **User scope** only when the agent must act as the authorizing Slack user.

    - Enter your credentials:
      - Client ID
      - Client Secret
      - Permissions (scopes — see [Slack Scopes documentation](https://api.slack.com/scopes))

      > Image: Add credentials in Scalekit dashboard
    - Click **Save**.

## Code examples

Connect a user's Slack account and make API calls on their behalf — Scalekit handles OAuth and token management automatically.

## Proxy API Calls

  ### Node.js

```typescript

const connectionName = 'slack'; // get your connection name from connection configurations
const identifier = 'user_123';  // your unique user identifier

// Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);
const actions = scalekit.actions;

// Authenticate the user
const { link } = await actions.getAuthorizationLink({
  connectionName,
  identifier,
});
console.log('🔗 Authorize Slack:', link);
process.stdout.write('Press Enter after authorizing...');
await new Promise(r => process.stdin.once('data', r));

// Make a request via Scalekit proxy
const result = await actions.request({
  connectionName,
  identifier,
  path: '/api/auth.test',
  method: 'POST',
});
console.log(result);

// If you use slack_fetch_conversation_history, message text can contain
// Slack mention tokens like <@U09NZ1V7KPF>. Resolve the user ID with
// slack_get_user_info before showing messages to end users.
```

  ### Python

```python

from dotenv import load_dotenv
load_dotenv()

connection_name = "slack"  # get your connection name from connection configurations
identifier = "user_123"     # your unique user identifier

# Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

# Authenticate the user
link_response = actions.get_authorization_link(
    connection_name=connection_name,
    identifier=identifier
)
# present this link to your user for authorization, or click it yourself for testing
print("🔗 Authorize Slack:", link_response.link)
input("Press Enter after authorizing...")

# Make a request via Scalekit proxy
result = actions.request(
    connection_name=connection_name,
    identifier=identifier,
    path="/api/auth.test",
    method="POST"
)
print(result)

# If you use slack_fetch_conversation_history, message text can contain
# Slack mention tokens like <@U09NZ1V7KPF>. Resolve the user ID with
# slack_get_user_info before showing messages to end users.
```

## Tool list

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for the current user first.

## Tool list

### `slack_add_reaction`

Add an emoji reaction to a message in Slack. Requires a valid Slack OAuth2 connection with reactions:write scope.

Parameters:

- `channel` (`string`, required): Channel ID or channel name where the message exists
- `name` (`string`, required): Emoji name to react with (without colons)
- `timestamp` (`string`, required): Timestamp of the message to add reaction to

### `slack_create_channel`

Creates a new public or private channel in a Slack workspace. Requires a valid Slack OAuth2 connection with channels:manage scope for public channels or groups:write scope for private channels.

Parameters:

- `name` (`string`, required): Name of the channel to create (without # prefix)
- `is_private` (`boolean`, optional): Create a private channel instead of public
- `team_id` (`string`, optional): Encoded team ID to create channel in (if using org tokens)

### `slack_delete_message`

Deletes a message from a Slack channel or direct message. Requires a valid Slack OAuth2 connection with chat:write scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM where the message was sent
- `ts` (`string`, required): Timestamp of the message to delete

### `slack_fetch_conversation_history`

Fetches conversation history from a Slack channel or direct message with pagination support. Requires a valid Slack OAuth2 connection with channels:history scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM
- `cursor` (`string`, optional): Paginate through collections by cursor for pagination
- `latest` (`string`, optional): End of time range of messages to include in results
- `limit` (`integer`, optional): Number of messages to return (1-1000, default 100)
- `oldest` (`string`, optional): Start of time range of messages to include in results

### `slack_get_conversation_info`

Retrieve information about a Slack channel, including metadata, settings, and member count. Requires a valid Slack OAuth2 connection with channels:read scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM
- `include_locale` (`boolean`, optional): Set to true to include the locale for this conversation
- `include_num_members` (`boolean`, optional): Set to true to include the member count for the conversation

### `slack_get_conversation_replies`

Retrieve replies to a specific message thread in a Slack channel or direct message. Requires a valid Slack OAuth2 connection with channels:history or groups:history scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM
- `ts` (`string`, required): Timestamp of the parent message to get replies for
- `cursor` (`string`, optional): Pagination cursor for retrieving next page of results
- `inclusive` (`boolean`, optional): Include messages with latest or oldest timestamp in results
- `latest` (`string`, optional): End of time range of messages to include in results
- `limit` (`integer`, optional): Number of messages to return (default 100, max 1000)
- `oldest` (`string`, optional): Start of time range of messages to include in results

### `slack_get_user_info`

Retrieves detailed information about a specific Slack user, including profile data, status, and workspace information. Requires a valid Slack OAuth2 connection with users:read scope.

Parameters:

- `user` (`string`, required): User ID to get information about
- `include_locale` (`boolean`, optional): Set to true to include locale information for the user

### `slack_get_user_presence`

Gets the current presence status of a Slack user (active, away, etc.). Indicates whether the user is currently online and available. Requires a valid Slack OAuth2 connection with users:read scope.

Parameters:

- `user` (`string`, required): User ID to check presence for

### `slack_invite_users_to_channel`

Invites one or more users to a Slack channel. Requires a valid Slack OAuth2 connection with channels:write scope for public channels or groups:write for private channels.

Parameters:

- `channel` (`string`, required): Channel ID or channel name (#general) to invite users to
- `users` (`string`, required): Comma-separated list of user IDs to invite to the channel

### `slack_join_conversation`

Joins an existing Slack channel. The authenticated user will become a member of the channel. Requires a valid Slack OAuth2 connection with channels:write scope for public channels.

Parameters:

- `channel` (`string`, required): Channel ID or channel name (#general) to join

### `slack_leave_conversation`

Leaves a Slack channel. The authenticated user will be removed from the channel and will no longer receive messages from it. Requires a valid Slack OAuth2 connection with channels:write scope for public channels or groups:write for private channels.

Parameters:

- `channel` (`string`, required): Channel ID or channel name (#general) to leave

### `slack_list_channels`

List all public and private channels in a Slack workspace that the authenticated user has access to. Requires a valid Slack OAuth2 connection with channels:read, groups:read, mpim:read, and/or im:read scopes depending on conversation types needed.

Parameters:

- `cursor` (`string`, optional): Pagination cursor for retrieving next page of results
- `exclude_archived` (`boolean`, optional): Exclude archived channels from the list
- `limit` (`integer`, optional): Number of channels to return (default 100, max 1000)
- `team_id` (`string`, optional): Encoded team ID to list channels for (optional)
- `types` (`string`, optional): Mix and match channel types (public_channel, private_channel, mpim, im)

### `slack_list_users`

Lists all users in a Slack workspace, including information about their status, profile, and presence. Requires a valid Slack OAuth2 connection with users:read scope.

Parameters:

- `cursor` (`string`, optional): Pagination cursor for fetching additional pages of users
- `include_locale` (`boolean`, optional): Set to true to include locale information for each user
- `limit` (`number`, optional): Number of users to return (1-1000)
- `team_id` (`string`, optional): Encoded team ID to list users for (if using org tokens)

### `slack_lookup_user_by_email`

Find a user by their registered email address in a Slack workspace. Requires a valid Slack OAuth2 connection with users:read.email scope. Cannot be used by custom bot users.

Parameters:

- `email` (`string`, required): Email address to search for users by

### `slack_pin_message`

Pin a message to a Slack channel. Pinned messages are highlighted and easily accessible to channel members. Requires a valid Slack OAuth2 connection with pins:write scope.

Parameters:

- `channel` (`string`, required): Channel ID or channel name where the message exists
- `timestamp` (`string`, required): Timestamp of the message to pin

### `slack_send_message`

Sends a message to a Slack channel or direct message. Requires a valid Slack OAuth2 connection with chat:write scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM
- `text` (`string`, required): Message text content
- `attachments` (`string`, optional): JSON-encoded array of attachment objects for additional message formatting
- `blocks` (`string`, optional): JSON-encoded array of Block Kit block elements for rich message formatting
- `reply_broadcast` (`boolean`, optional): Used in conjunction with thread_ts to broadcast reply to channel
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `thread_ts` (`string`, optional): Timestamp of parent message to reply in thread
- `tool_version` (`string`, optional): Optional tool version to use for execution
- `unfurl_links` (`boolean`, optional): Enable or disable link previews
- `unfurl_media` (`boolean`, optional): Enable or disable media link previews

### `slack_set_user_status`

Set the user's custom status with text and emoji. This appears in their profile and can include an expiration time. Requires a valid Slack OAuth2 connection with users.profile:write scope.

Parameters:

- `status_emoji` (`string`, optional): Emoji to display with status (without colons)
- `status_expiration` (`integer`, optional): Unix timestamp when status should expire
- `status_text` (`string`, optional): Status text to display

### `slack_update_message`

Updates/edits a previously sent message in a Slack channel or direct message. Requires a valid Slack OAuth2 connection with chat:write scope.

Parameters:

- `channel` (`string`, required): Channel ID, channel name (#general), or user ID for DM where the message was sent
- `ts` (`string`, required): Timestamp of the message to update
- `attachments` (`string`, optional): JSON-encoded array of attachment objects for additional message formatting
- `blocks` (`string`, optional): JSON-encoded array of Block Kit block elements for rich message formatting
- `text` (`string`, optional): New message text content


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
