# slack-bolt

> The Bolt Framework for Python

- **URL**: https://www.freshcrate.ai/projects/slack-bolt
- **Author**: Slack Technologies
- **Category**: Frameworks
- **Latest version**: `1.28.0` (2026-04-21)
- **License**: MIT
- **Source**: https://github.com/slackapi/bolt-python
- **Language**: Python
- **GitHub**: 1,291 stars, 288 forks
- **Registry**: pypi (`slack-bolt`)
- **Tags**: `pypi`

## Description

<h1 align="center">Bolt <img src="https://docs.slack.dev/img/logos/bolt-py-logo.svg" alt="Bolt logo" width="32"/> for Python</h1>

<p align="center">
    <a href="https://pypi.org/project/slack-bolt/">
        <img alt="PyPI - Version" src="https://img.shields.io/pypi/v/slack-bolt"></a>
    <a href="https://codecov.io/gh/slackapi/bolt-python">
        <img alt="Codecov" src="https://img.shields.io/codecov/c/gh/slackapi/bolt-python"></a>
    <a href="https://pepy.tech/project/slack-bolt">
        <img alt="Pepy Total Downloads" src="https://img.shields.io/pepy/dt/slack-bolt"></a>
    <br>
    <a href="https://pypi.org/project/slack-bolt/">
        <img alt="Python Versions" src="https://img.shields.io/pypi/pyversions/slack-bolt.svg"></a>
    <a href="https://docs.slack.dev/tools/bolt-python/">
        <img alt="Documentation" src="https://img.shields.io/badge/dev-docs-yellow"></a>
</p>

A Python framework to build Slack apps in a flash with the latest platform features. Read the [getting started guide](https://docs.slack.dev/tools/bolt-python/getting-started) and look at our [code examples](https://github.com/slackapi/bolt-python/tree/main/examples) to learn how to build apps using Bolt. The Python module documents are available [here](https://docs.slack.dev/tools/bolt-python/reference/).

## Setup

```bash
# Python 3.7+ required
python -m venv .venv
source .venv/bin/activate

pip install -U pip
pip install slack_bolt
```

## Creating an app

Create a Bolt for Python app by calling a constructor, which is a top-level export. If you'd prefer, you can create an [async app](#creating-an-async-app).

```python
import logging
logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App

# export SLACK_SIGNING_SECRET=***
# export SLACK_BOT_TOKEN=xoxb-***
app = App()

# Add functionality here

if __name__ == "__main__":
    app.start(3000)  # POST http://localhost:3000/slack/events
```

## Running an app

```bash
export SLACK_SIGNING_SECRET=***
export SLACK_BOT_TOKEN=xoxb-***
python app.py

# in another terminal
ngrok http 3000
```

## Running a Socket Mode app

If you use [Socket Mode](https://docs.slack.dev/apis/events-api/using-socket-mode/) for running your app, `SocketModeHandler` is available for it.

```python
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# Install the Slack app and get xoxb- token in advance
app = App(token=os.environ["SLACK_BOT_TOKEN"])

# Add functionality here

if __name__ == "__main__":
    # Create an app-level token with connections:write scope
    handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
    handler.start()
```

Run the app this way:

```bash
export SLACK_APP_TOKEN=xapp-***
export SLACK_BOT_TOKEN=xoxb-***
python app.py

# SLACK_SIGNING_SECRET is not required
# Running ngrok is not required
```

## Listening for events

Apps typically react to a collection of incoming events, which can correspond to [Events API events](https://docs.slack.dev/apis/events-api/), [actions](https://docs.slack.dev/block-kit/#making-things-interactive), [shortcuts](https://docs.slack.dev/interactivity/implementing-shortcuts/), [slash commands](https://docs.slack.dev/interactivity/implementing-slash-commands/) or [options requests](https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element#external_select). For each type of
request, there's a method to build a listener function.

```python
# Listen for an action from a Block Kit element (buttons, select menus, date pickers, etc)
app.action(action_id)(fn)

# Listen for dialog submissions
app.action({"callback_id": callbackId})(fn)

# Listen for slash commands
app.command(command_name)(fn)

# Listen for an event from the Events API
app.event(event_type)(fn)

# Listen for a custom step execution from a workflow
app.function(callback_id)(fn)

# Convenience method to listen to only `message` events using a string or re.Pattern
app.message([pattern ,])(fn)

# Listen for options requests (from select menus with an external data source)
app.options(action_id)(fn)

# Listen for a global or message shortcuts
app.shortcut(callback_id)(fn)

# Listen for view_submission modal events
app.view(callback_id)(fn)
```

The recommended way to use these methods are decorators:

```python
@app.event(event_type)
def handle_event(event):
    pass
```

## Making things happen

Most of the app's functionality will be inside listener functions (the `fn` parameters above). These functions are called with a set of arguments, each of which can be used in any order. If you'd like to access arguments off of a single object, you can use `args`, an [`slack_bolt.kwargs_injection.Args`](https://github.com/slackapi/bolt-python/blob/main/slack_bolt/kwargs_injection/args.py) instance that contains all available arguments for that event.

| Argument  | Description  |
| :---: | :--- |
| `body` | Dictionary that contains the entire body of the request (superset of `payload`). Some accessory data is

## Recent releases

| Version | Date | Urgency | Changes |
| --- | --- | --- | --- |
| `1.28.0` | 2026-04-21 | Low | Imported from PyPI (1.28.0) |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |
| `v1.28.0` | 2026-04-06 | Medium | ## What's Changed  Bring magic to a conversation with `say_stream` for [streaming messages](https://docs.slack.dev/ai/developing-agents#streaming) and show loading status with `set_status`. Now available for `app.event` and `app.message` listeners:  ```python @app.event("app_mention") def handle_mention(say_stream, set_status):     set_status(         status="Thinking...",         loading_messages=["Waking up...", "Loading a witty response..."],     )     stream = say_stream(buffer_si |

## Citation

- HTML: https://www.freshcrate.ai/projects/slack-bolt
- Markdown: https://www.freshcrate.ai/projects/slack-bolt.md
- Dependencies JSON: https://www.freshcrate.ai/api/projects/slack-bolt/deps

_Generated by freshcrate.ai. Indexes pypi releases for AI-agent ecosystem packages._
