NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #346 most downloaded on PyPI
The Slack API Platform SDK for Python
Last release 17 days ago
03 Sep 2026
Ships fairly regularly
a new release about every 2 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
134 releases · first in 2020
One column per quarter.
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/61?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/60?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/53?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/58?closed=1
__all__ to __init__.py - Thanks @seratch @kezabelleAdd new properties to Audit Logs API response classes - Thanks @seratch
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/56?closed=1
domain to team.info API parameters - Thanks @seratchUpdate Audit Logs API response - Thanks @seratch
user_ids parameter bug in conversations.inviteShared API method - Thanks @seratchAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/51?closed=1
Add `bookmarks.*` API support (via #1176) - thanks @filmaj!
bookmarks.* API support (via #1176) - thanks @filmaj!ssl_context to SocketModeHandler if it is defined in the web_client (via #1177) - thanks @charlch!admin.users.unsupportedVersions.export API support (via #1174) - thanks @seratch!All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/52?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/49?closed=1
admin.apps.requests.cancel API method support - Thanks @seratchasyncio.CancelledError if the connection is already closed - Thanks @seratch @vectoralphaaccessibility_label to button block element - Thanks @seratchAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/46?closed=1
Add Support for Subscribe in Slack (apps.manifest.*) by @srajiang in #1151
Add Support for Subscribe in Slack (apps.manifest.*) by @srajiang in #1151
This release includes support for apps.notifications.subscriptions.* endpoints and adds message metadata field to the chat.postMessage and chat.update arguments.
apps.notifications.subscriptions.create apps.notifications.subscriptions.update apps.notifications.subscriptions.delete
Full Changelog: v3.13.0...v3.130b1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/45?closed=1
team.* & admin.users.session.resetBulk APIs - Thanks @seratchslack_sdk.models classes - Thanks @seratchchannel_posting_permissions_updated action - Thanks @seratchAdd Support for App Manifest Endpoints (apps.manifest.*) by @misscoded in https://github.com/slackapi/python-slack-sdk/pull/1123
This release includes support for app manifests. The apps.manifest.* endpoints can be used to create, delete, update, and copy your Slack apps with ease. New endpoints include:
apps.manifest.createapps.manifest.deleteapps.manifest.exportapps.manifest.updateapps.manifest.validatetooling.tokens.rotateFull Changelog: https://github.com/slackapi/python-slack-sdk/compare/v3.11.2...v3.12.0b1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/48?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/47?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/43?closed=1
Refer to v3.11.0 release notes
Refer to v3.11.0 release notes
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/44?closed=1
Since this version, all the methods in WebClient / AsyncWebClient have not only required arguments but also all possible ones in the method signature
WebClient / AsyncWebClientSince this version, all the methods in WebClient / AsyncWebClient have not only required arguments but also all possible ones in the method signature for better developer experience. Refer to the pull request enabling this #1099 for details.
Now that SlackResponse / AsyncSlackResponse now have __contains__ method, you can test if a key exists in WebClient responses. Refer to the pull request enabling this #1104 for details.
token = "xoxb-"
response = WebClient(token).auth_test()
"error" in response # True / False
__contains__ method in slack_sdk.web.SlackResponse / AsyncSlackResponse - Thanks @seratchContextBlock element type hint - Thanks @uroboro @seratchget/__getitem__ method behavior when response body is empty - Thanks @janeliang0522 @seratchAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/42?closed=1
Sign in with Slack helps users log into your service using their Slack profile. The platform feature was recently upgraded to be compatible with the s
Sign in with Slack helps users log into your service using their Slack profile. The platform feature was recently upgraded to be compatible with the standard OpenID Connect specification. With this version of slack-sdk, implementing the auth flow is much easier.
When you create a new Slack app, set the following user scopes:
oauth_config:
redirect_urls:
- https://{your-domain}/slack/oauth_redirect
scopes:
user:
- openid # required
- email # optional
- profile # optional
Check the Flask example in the repository. It does the following:
slack_sdk.oauth.OpenIDConnectAuthorizeUrlGenerator helps you easily do thisOAuthStateStore is still available for generating state parameter value (it's available for nonce management too)WebClient can perform openid.connect.token API calls with given code parameterIf you want to know the way with asyncio, check the Sanic app example in the same directory.
This version introduces a built-in retry functionalities to the following API clients:
slack_sdk.web.WebClientslack_sdk.webhook.WebhookClientslack_sdk.audit_logs.AuditLogsClientslack_sdk.scim.SCIMClientslack_sdk.web.async_client.AsyncWebClient (aiohttp/asyncio compatible)slack_sdk.webhook.async_client.AsyncWebhookClient (aiohttp/asyncio compatible)slack_sdk.audit_logs.async_client.AsyncAuditLogsClient (aiohttp/asyncio compatible)slack_sdk.scim.async_client.AsyncSCIMClient (aiohttp/asyncio compatible)With the default settings, only slack_sdk.http_retry.builtin_handlers.ConnectionErrorRetryHandler (AsyncConnectionErrorRetryHandler for asyncio clients) with its default configuratio (=only one retry in the manner of exponential backoff and jitter) is enabled in the above clients. The retry handler retries if an API client encounters a connectivity-related failure (e.g., Connection reset by peer).
import os
from slack_sdk.web import WebClient
# Only ConnectionErrorRetryHandler is enabled
client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
Another built-in retry handler is the one that handles rate limited errors.
# --------------------------------
# Use the built-in handlers
# --------------------------------
client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
# This handler does retries when HTTP status 429 is returned
from slack_sdk.http_retry.builtin_handlers import RateLimitErrorRetryHandler
rate_limit_handler = RateLimitErrorRetryHandler(max_retry_count=1)
# Enable rate limited error retries as well
cient.retry_handlers.append(rate_limit_handler)
Creating your own ones is also quite simple. Defining a new class that inherits slack_sdk.http_retry.RetryHandler and implements required methods (internals of can_retry / prepare_for_next_retry). Check the built-in ones' source code for learning how to properly implement.
# --------------------------------
# Create your own one
# --------------------------------
import socket
from typing import Optional
from slack_sdk.http_retry import (RetryHandler, RetryState, HttpRequest, HttpResponse)
from slack_sdk.http_retry.builtin_interval_calculators import (
BackoffRetryIntervalCalculator,
)
from slack_sdk.http_retry.jitter import RandomJitter
class MyRetryHandler(RetryHandler):
def _can_retry(
self,
*,
state: RetryState,
request: HttpRequest,
response: Optional[HttpResponse] = None,
error: Optional[Exception] = None
) -> bool:
# [Errno 104] Connection reset by peer
return (
error is not None and isinstance(error, socket.error) and error.errno == 104
)
# Customize the settings
my_handler = MyRetryHandler(
max_retry_count=2, # retry twice at maximum; the default is 1
interval_calculator=BackoffRetryIntervalCalculator( # exponential backoff and jitter is the default
backoff_factor=1.0, # 1, 2, 4, 8, 16 seconds later ...
jitter=RandomJitter(), # will add 0.0 -- 1.0 second to the backoff duration
),
)
client = WebClient(
token=os.environ["SLACK_BOT_TOKEN"],
retry_handlers=[rate_limit_handler, my_handler],
)
For asyncio apps, Async prefixed corresponding modules are available. All the methods in those methods are async/await compatible. Check the source code and tests for more details.
Refer to the v3.9.0 release note
Refer to the v3.9.0 release note
Refer to the v3.9.0 release note
Refer to the v3.9.0 release note
This version includes the token rotation feature support for better security. Refer to the API document for the general information about the feature.
This version includes the token rotation feature support for better security. Refer to the API document for the general information about the feature.
Apart from the column additions for the feature (specifically, refresh token + expiration date time) and the corresponding changes in your app code, no significant code is needed. Checking the example apps using Flask, Sanic in this directory can be helpful to learn what to do.
In a nutshell, you can call the following rotate_tokens method before handling every single incoming request from Slack. As long as your InstallationStore support the token rotation patterns, the code below should work as-is.
from slack_sdk.oauth.token_rotation import TokenRotator
from slack_sdk.oauth.installation_store import FileInstallationStore
# This instance can be singleton; thread-safe
token_rotator = TokenRotator(
# These are required for refreshing tokens
client_id=client_id,
client_secret=client_secret,
)
# Your own InstallationStore here
installation_store = FileInstallationStore()
def rotate_tokens(
enterprise_id: Optional[str] = None,
team_id: Optional[str] = None,
user_id: Optional[str] = None,
is_enterprise_install: Optional[bool] = None,
):
installation = installation_store.find_installation(
enterprise_id=enterprise_id,
team_id=team_id,
user_id=user_id,
is_enterprise_install=is_enterprise_install,
)
if installation is not None:
# If rotation does not occur, refreshed_installation is None
refreshed_installation = token_rotator.perform_token_rotation(installation=installation)
if refreshed_installation is not None:
# Save the new access token for the following processes
installation_store.save(refreshed_installation)
SQLAlchemyInstallationStore usersIf your app uses the built-in SQLAlchemyInstallationStore for managing Slack app installations, adding the following database columns is required for this version upgrade. Refer to the code to check the complete ones.
Also, since this version, all the table columns for string data have their max length for better compatibility with MySQL. We recommend setting the same ones for your models.
Column("bot_refresh_token", String(200)),Column("bot_token_expires_at", DateTime),Column("user_refresh_token", String(200)),Column("user_token_expires_at", DateTime),Column("bot_refresh_token", String(200)),Column("bot_token_expires_at", DateTime),Nothing published for this version
Nothing published for this version
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/37?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/35?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/36?closed=1
Since this version, the following methods are available to use for better installation data management.
InstallationStore / AsyncInstallationStoreSince this version, the following methods are available to use for better installation data management.
All the built-in implementations already support these methods. We recommend subscribing to tokens_revoked / app_uninstalled bot events and call these methods in the event handlers.
We recently started hosting the Python module documents at https://slack.dev/python-slack-sdk/api-docs/slack_sdk/
The new admin.users.session.* APIs for Enterprise Grid customers are supported in WebClient and AsyncWebClient.
In addition to the new features mentioned above, we've resolved a few issues in the slack_sdk.models classes. Also, we've improved the consistency of docstrings in this project.
slack_sdk.models usage in Web APIs - Thanks @invokermain @seratchslack_sdk.models.blocks.Option's description value is invalid in blocks - Thanks @seratchNothing published for this version
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/34?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/33?closed=1
text missing" warning is technically not always accurate - Thanks @eddygIn this version, better proxy configuration supports are added to all API clients support.
In this version, better proxy configuration supports are added to all API clients support.
http://{username}:{password}@{host}:{port} format support
HTTPS_PROXY / HTTP_PROXY env variables supportWe've improved the internals of RTMClient v2 in this release. If you are using the module, we highly recommend upgrading to this version.
HTTPS_PROXY / HTTP_PROXY env variable supports in all API clients - Thanks @seratchslack_sdk.models.messages and slack_sdk.models.dialoags (misspelled name) - Thanks @seratch @eddygAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/30?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/29?closed=1
SCIMClient/AsyncSCIMClient - Thanks @seratchSince this version, we support SCIM API and Audit Logs API.
Since this version, we support SCIM API and Audit Logs API.
Refer to the documents for details.
Nothing published for this version
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/26?closed=1
aiohttp.ClientSession in Socket Mode AIOHTTP adapter - Thanks @cxlai @seratchThis version includes support for Socket Mode, which enables developers to receive interactivy payalods and events through WebSocket connections.
This version includes support for Socket Mode, which enables developers to receive interactivy payalods and events through WebSocket connections.
https://api.slack.com/socket-mode
For WebSocket connection handling, there are four implementations including major 3rd party open-source libraries.
| PyPI Project | SocketModeClient |
|---|---|
| skack_sdk | slack_sdk.socket_mode.SocketModeClient |
| websocket_client | slack_sdk.socket_mode.websocket_client.SocketModeClient |
| aiohttp (asyncio-based) | slack_sdk.socket_mode.aiohttp.SocketModeClient |
| websockets (asyncio-based) | slack_sdk.socket_mode.websockets.SocketModeClient |
Here is a minimal working example with the built-in WebSocket client. You can switch to other implementation by changing the imports and adding the extra dependencies (websocket_client, aiohttp, websockets).
import os
from slack_sdk.web import WebClient
from slack_sdk.socket_mode import SocketModeClient
# Initialize SocketModeClient with an app-level token + WebClient
client = SocketModeClient(
# This app-level token will be used only for establishing a connection
app_token=os.environ.get("SLACK_APP_TOKEN"), # xapp-A111-222-xyz
# You will be using this WebClient for performing Web API calls in listeners
web_client=WebClient(token=os.environ.get("SLACK_BOT_TOKEN")) # xoxb-111-222-xyz
)
from slack_sdk.socket_mode.response import SocketModeResponse
from slack_sdk.socket_mode.request import SocketModeRequest
def process(client: SocketModeClient, req: SocketModeRequest):
if req.type == "events_api":
# Acknowledge the request anyway
response = SocketModeResponse(envelope_id=req.envelope_id)
client.send_socket_mode_response(response)
# Add a reaction to the message if it's a new message
if req.payload["event"]["type"] == "message" \
and req.payload["event"].get("subtype") is None:
client.web_client.reactions_add(
name="eyes",
channel=req.payload["event"]["channel"],
timestamp=req.payload["event"]["ts"],
)
# Add a new listener to receive messages from Slack
# You can add more listeners like this
client.socket_mode_request_listeners.append(process)
# Establish a WebSocket connection to the Socket Mode servers
client.connect()
# Just not to stop this process
from threading import Event
Event().wait()
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
The following changes are related to documents and tutorial contents:
WebClient#files_upload fails with the default team_id param for Org-wide installations - Thanks @gburek-fastly @seratchWebClient#files_upload's file argument - Thanks @gburek-fastly @seratchThe following changes are related to documents and tutorial contents:
This version includes the changes related to Org-Wide App feature, which is for Enterprise Grid organizations.
This version includes the changes related to Org-Wide App feature, which is for Enterprise Grid organizations.
https://api.slack.com/enterprise/apps
InstallationStore#find_installation from InstallationStore#find_bot in authorize functionsteam_access_granted / team_access_removedis_enterprise_install: bool in context objectIf you're already using a built-in InstallationStore implementation, the following fields in the data row will be expected since v3.1. If your app uses relational database tables, please add the corresponding columns to the tables.
is_enterprise_install: bool (true if it is an org-level installation)enterprise_url: Optional[str] (URL; this is available only for org-level installation)enterprise_name: Optional[str] (the name of the installed org; this value is just a snapshot data at the timing of installations. So, it can be changed afterwards)team_name: Optional[str] (the name of the installed workspace)incoming_webhook_channel: Optional[str] (channel name)token_type: Optional[str]Also, since this version, the built-in InstallationStore based authorize functions try to fetch Installation. The Installation object contains Bot data too. So, you will be able to utilize more fields like user_token, thanks to this change.
If your application does not maintain the data when handling Slack app installations, upgrading to this version may result in errors due to this incompatibility. If you need to continue using Bot over Installation data rows, please consider implementing and using your own Authorize classes.
PlainTextInputElement class comment fix - Thanks @jelizaga3-gatechNothing published for this version
Nothing published for this version
v3.1.0 includes org-level installation support (for Enterprise Grid users). The detailed release note will be available soon.
v3.1.0 includes org-level installation support (for Enterprise Grid users). The detailed release note will be available soon.
Renamed packages (from slack to slack_sdk) with deprecation warnings
This is the first stable version of slack_sdk v3. The remarkable updates in this major version are:
WebClient and WebhookClientslack to slack_sdk) with deprecation warningsRefer to the documents for details. The migration guide for slackclient v2.x users is available at https://slack.dev/python-slack-sdk/v3-migration/
This is the first stable version of slack_sdk v3. The remarkable updates in this major version are:
WebClient and WebhookClientslack to slack_sdk) with deprecation warningsRefer to v3.0.0 milestone and the docs website for details. If you're a slackclient user, the migration guide for slackclient v2.x users is available at http://localhost:3000/python-slack-sdk/v3-migration.
Your coding agent can read these notes before it upgrades. Set up the MCP server →