NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #317 most downloaded on PyPI
The Slack API Platform SDK for Python
Last release 3 days ago
01 Oct 2026
Ships fairly regularly
a new release about every 6 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
135 releases · first in 2020
One column per quarter.
feat(models): add ContainerBlock for block kit by @srtaalej in #1949
Full Changelog: v3.44.1...v3.45.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/122?closed=1
fix: stop aiohttp Socket Mode connect() retrying forever after close by @WilliamBergamin in #1956
Full Changelog: v3.44.0...v3.44.1
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/121?closed=1
feat(oauth): add StatelessOAuthStateStore using JWT by @muskaannnr in #1916
Full Changelog: v3.43.0...v3.44.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/120
⚠️ Warning: A signing secret is now required to exist when validating requests. Apps that receive events with Socket Mode should update to Bolt for Py
⚠️ Warning: A signing secret is now required to exist when validating requests. Apps that receive events with Socket Mode should update to Bolt for Python
1.29.0to avoid errors at initialization. Please refer to this issue: #1903
style attribute to RichTextElementParts.Date & friends by @Lexicality in #1882Full Changelog: v3.42.0...v3.43.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/119
fix: pass default ssl=True to aiohttp to avoid deprecation warning by @WilliamBergamin in #1843
SignatureVerifier by @BHSPitMonkey in #1845Full Changelog: v3.41.0...v3.42.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/118?closed=1
feat: add support for apps.user.connection.update by @WilliamBergamin in #1835
Full Changelog: v3.40.1...v3.41.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/117?closed=1
fix: rely on naive datetime for sqlalchemy by @WilliamBergamin in #1833
Full Changelog: v3.40.0...v3.40.1
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/116?closed=1
Agent Thinking Steps: Display Tasks/Tools, Plans, and Markdown Text
Now, you can display a mixture of structured content called "chunks":
Available in:
chat_startStream, chat_appendStream, and chat_stopStreamstreamer = client.chat_stream(...), streamer.append(...)$ slack create
# → AI Agent App
# Bolt for JavaScript
# → Bolt for Pythonstreamer = client.chat_stream(
channel=channel_id,
recipient_team_id=team_id,
recipient_user_id=user_id,
thread_ts=thread_ts,
task_display_mode="plan",
)
streamer.append(
chunks=[
MarkdownTextChunk(
text="Hello.\nI have received the task. ",
),
MarkdownTextChunk(
text="This task appears manageable.\nThat is good.",
),
TaskUpdateChunk(
id="001",
title="Understanding the task...",
status="in_progress",
details="- Identifying the goal\n- Identifying constraints",
),
TaskUpdateChunk(
id="002",
title="Performing acrobatics...",
status="pending",
),
],
)
time.sleep(4)
streamer.append(
chunks=[
PlanUpdateChunk(
title="Adding the final pieces...",
),
TaskUpdateChunk(
id="001",
title="Understanding the task...",
status="complete",
details="\n- Pretending this was obvious",
output="We'll continue to ramble now",
),
TaskUpdateChunk(
id="002",
title="Performing acrobatics...",
status="in_progress",
),
],
)
time.sleep(4)
streamer.stop(
chunks=[
PlanUpdateChunk(
title="Decided to put on a show",
),
TaskUpdateChunk(
id="002",
title="Performing acrobatics...",
status="complete",
details="- Jumped atop ropes\n- Juggled bowling pins\n- Rode a single wheel too",
),
MarkdownTextChunk(
text="The crowd appears to be astounded and applauds :popcorn:"
),
],
blocks=create_feedback_block(),
)Full Changelog: v3.39.0...v3.40.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/115
feat: accept chunks as arguments to chat.{start,append,stop}Stream methods by @zimeg in #1806
Full Changelog: v3.39.0...v3.40.0.dev0
feat: Add work objects support by @vegeris in #1783 and #1793
Full Changelog: v3.38.0...v3.39.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/114?closed=1
feat(models): add underline to rich text section block element by @zimeg in #1771
black by @WilliamBergamin in #1778Full Changelog: v3.37.0...v3.38.0
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/113?closed=1
AI-Enabled Features: Loading States, Text Streaming, and Feedback Buttons
Try the AI Agent Sample app to explore the AI-enabled features and existing Assistant helper:
# Create a new AI Agent app
$ slack create slack-ai-agent-app --template slack-samples/bolt-python-assistant-template
$ cd slack-ai-agent-app/
# Initialize Python Virtual Environment
$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
# Add your OPENAI_API_KEY
$ export OPENAI_API_KEY=sk-proj-ahM...
# Run the local dev server
$ slack runAfter the app starts, send a message to the "slack-ai-agent-app" bot for a unique response.
Loading states allows you to not only set the status (e.g. "My app is typing...") but also sprinkle some personality by cycling through a collection of loading messages:
@app.message()
def handle_message(message, client):
client.assistant_threads_setStatus(
channel_id=channel_id,
thread_ts=thread_ts,
status="thinking...",
loading_messages=[
"Teaching the hamsters to type faster…",
"Untangling the internet cables…",
"Consulting the office goldfish…",
"Polishing up the response just for you…",
"Convincing the AI to stop overthinking…",
],
)
# Start a new message streamThe chat_stream() helper utility can be used to streamline calling the 3 text streaming methods:
# Start a new message stream
streamer = client.chat_stream(
channel=channel_id,
recipient_team_id=team_id,
recipient_user_id=user_id,
thread_ts=thread_ts,
)
# Loop over OpenAI response stream
# https://platform.openai.com/docs/api-reference/responses/create
for event in returned_message:
if event.type == "response.output_text.delta":
streamer.append(markdown_text=f"{event.delta}")
else:
continue
feedback_block = create_feedback_block()
streamer.stop(blocks=feedback_block)Alternative to the Text Streaming Helper is to call the individual methods.
client.chat_startStreamFirst, start a chat text stream to stream a response to any message:
@app.message()
def handle_message(client, context, event, messsage):
# Start a new message stream
stream_response = client.chat_startStream(
channel=channel_id,
recipient_team_id=team_id,
recipient_user_id=user_id,
thread_ts=thread_ts,
)
stream_ts = stream_response["ts"]client.chat_appendStreamAfter starting a chat text stream, you can then append text to it in chunks (often from your favourite LLM SDK) to convey a streaming effect:
for event in returned_message:
if event.type == "response.output_text.delta":
client.chat_appendStream(
channel=channel_id,
ts=stream_ts,
markdown_text=f"{event.delta}"
)
else:
continueclient.chat_stopStreamLastly, you can stop the chat text stream to finalize your message:
client.chat_stopStream(
channel=channel_id,
ts=stream_ts,
blocks=feedback_block
)Add feedback buttons to the bottom of a message, after stopping a text stream, to gather user feedback:
def create_feedback_block() -> List[Block]:
blocks: List[Block] = [
ContextActionsBlock(
elements=[
FeedbackButtonsElement(
action_id="feedback",
positive_button=FeedbackButtonObject(
text="Good Response",
accessibility_label="Submit positive feedback on this response",
value="good-feedback",
),
negative_button=FeedbackButtonObject(
text="Bad Response",
accessibility_label="Submit negative feedback on this response",
value="bad-feedback",
),
)
]
)
]
return blocks
@app.message()
def handle_message(client, context, event, message):
# ... previous streaming code ...
# Stop the stream and add feedback buttons
feedback_block = create_feedback_block()
client.chat_stopStream(
channel=channel_id,
ts=stream_ts,
blocks=feedback_block
)chat_postMessage supports markdown_textresponse = client.chat_postMessage(
channel="C111",
markdown_text=markdown_content,
)Learn more in #1718
📚 https://docs.slack.dev/reference/block-kit/blocks/markdown-block/
from slack_sdk.models.blocks import MarkdownBlock
...
@app.message("hello")
def message_hello(say):
say(
blocks=[
MarkdownBlock(text="**lets's go!**"),
],
text="let's go!",
)Learn more in #1748
Add support for the workflows.featured.{add|list|remove|set} methods:
app.client.workflows_featured_add(channel_id="C0123456789", trigger_ids=["Ft0123456789"])
app.client.workflows_featured_list(channel_ids="C0123456789")
app.client.workflows_featured_remove(channel_id="C0123456789", trigger_ids=["Ft0123456789"])
app.client.workflows_featured_set(channel_id="C0123456789", trigger_ids=["Ft0123456789"])Learn more in #1712
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/112
Full Changelog: v3.36.0...v3.37.0
Package: https://pypi.org/project/slack-sdk/3.37.0/
feat: add support for elevate methods in #1703 - Thanks @WilliamBergamin !
Milestone: https://github.com/slackapi/python-slack-sdk/milestone/111
Full Changelog: v3.35.0...v3.36.0
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
feat: #1276 add Asyncio SQLAlchemy support by @galuszkak in https://github.com/slackapi/python-slack-sdk/pull/1633
channels param to files.upload v2 method by @seratch in https://github.com/slackapi/python-slack-sdk/pull/1641channel_id instead of channel in files_upload_v2 documentation by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1670feat: add support for python 3.13 by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1614
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/109?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/107?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/106?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/105?closed=1
Enable WebClient#assistant_threads_setSuggestedPrompts to skip title param - Thanks @seratch
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/103?closed=1
feat: add support for conversations.requestShared approve, deny & list by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1530
conversations.requestShared approve, deny & list by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1530feat: add new conversations.externalInvitePermissions.set API by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1517
conversations.externalInvitePermissions.set API by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1517team.externalTeams.disconnect by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1526bot_access_tokens from the debug logs of socket mode by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1519feat: add team.externalTeams.list by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1512
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/99?closed=1 Full Changelog: https://github.com/slackapi/python-slack-sdk/compare/v3.29.0...v3.30.0
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/97?closed=1
Added deprecation warnings to Steps from Apps methods by @WilliamBergamin in https://github.com/slackapi/python-slack-sdk/pull/1504
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/95?closed=1 Full Changelog: https://github.com/slackapi/python-slack-sdk/compare/v3.27.2...v3.28.0
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/94?closed=1
RichTextElement.elements items are never promoted to a proper Python object type - Thanks @k1e1n04 @kezabelleAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/93?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/91?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/90?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/89?closed=1
force argument to conversations.invite API method - Thanks @filmajAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/88?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/87?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/85?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/86?closed=1
Since this version, developers no longer need files:read permission for files_upload_v2 method. To learn more about files_upload_v2, please refer to v
RichTextInputElement to slack_sdk.models - Thanks @seratchfiles.upload v2 method in correspondence with server-side changes - Thanks @seratchSince this version, developers no longer need files:read permission for files_upload_v2 method. To learn more about files_upload_v2, please refer to v3.19.0 release notes: https://github.com/slackapi/python-slack-sdk/releases/tag/v3.19.0
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/80?closed=1
admin.* APIs for managing automation platform apps - Thanks @seratchworkflow_button block element to the slack_sdk.models package - Thanks @seratchmetadata argument support to Incoming Webhooks - Thanks @seratchteam.accessLogs API - Thanks @seratchServerErrorRetryHandler, renaming _can_retry_async -> _can_retry - Thanks @maximkir-flImageBlock's title parsing fails when given a string - Thanks @seratch @kezabelleauthor_subname to attachment model class - Thanks @seratchcreate_tables() to SQLAlchemyOAuthStateStore - Thanks @raphaelhuefnerstars.* API methods as deprecated - Thanks @seratchcodecov/codecov-action@v3 to upload code coverage - Thanks @zimegAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/82?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/81?closed=1
Update Audit Logs API response class to have newly added properties - Thanks @seratch
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/75?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/78?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/77?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/70?closed=1
admin.conversations.bulk{Archive|Delete|Move} API method support - Thanks @WilliamBergaminchat.postMessage method - Thanks @seratch @mwbrooksemoji.list API args - Thanks @seratchAll issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/75?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/73?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/72?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/71?closed=1
Improve WebClient#files_upload_v2() to use given filename as the default title value - Thanks @seratch @mattpr
WebClient#files_upload_v2() to use given filename as the default title value - Thanks @seratch @mattprWe've received many reports on the performance issue of the existing files.upload API (refer to #1191 #1165 for details). So, to cope with the problem
WebClient / AsyncWebClientWe've received many reports on the performance issue of the existing files.upload API (refer to #1191 #1165 for details). So, to cope with the problem, our platform team decided to unlock a new way to upload files to Slack via public APIs. To utilize the new approach, developers need to implement the following steps on their code side:
WebClient#files_getUploadURLExternal() method to receive a URL to use for each fileWebClient#files_completeUploadExternal() method with the pairs of file ID and title to complete the whole process, plus share the files in a channelWebClient#files_info() method for each fileWe do understand that writing the above code requires many lines of code. Also, the existing WebClient#files_upload() users have to take a certain amount of time for migration. To mitigate the pain, we've added a wrapper method named WebClient#files_upload_v2() on the SDK side.
Also, in addition to the performance improvements, another good news is that 3rd party apps can now upload multiple files at a time!
See the following code examples demonstrating how the wrapper method works:
import os
from slack_sdk import WebClient
client = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
# Legacy way
response = client.files_upload(
file="./logo.png",
title="New company logo",
channels=["C12345"],
initial_comment="Here is the latest version of our new company logo :wave:",
)
response.get("file") # returns the full metadata of the uploaded file
# New way - the same parameters works in most cases
response = client.files_upload_v2(
file="./logo.png",
title="New company logo",
# Note that channels still works but going with channel="C12345" is recommended
# channels=["C111", "C222"] is no longer supported. In this case, an exception can be thrown
channels=["C12345"],
initial_comment="Here is the latest version of our new company logo :wave:",
)
response.get("file") # returns the full metadata of the uploaded file
# New way with multiple files!
response = client.files_upload_v2(
file_uploads=[
{
"file": "./logo.png",
"title": "New company logo",
},
{
"content": "Minutes ....",
"filename": "team-meeting-minutes-2022-03-01.md",
"title": "Team meeting minutes (2022-03-01)",
},
],
channel="C12345",
initial_comment="Here is the latest version of our new company logo :wave:",
)
response.get("files") # returns the full metadata of all the uploaded files
When migrating to the v2 method, please note that the new method requires both UPDATE: Since v3.23.0, files:write and files:read scopes. If your existing apps have only files:write scope for uploading files, you need to add files:read to the scopes plus re-install the app to issue an updated token.files:read scope is no longer required.
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/68?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/67?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/66?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/65?closed=1
All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/63?closed=1
Your coding agent can read these notes before it upgrades. Set up the MCP server →