Expand description
§slack-web-api
Typed async Rust client for every Slack Web API method — all 330 of them, including admin.* —
built on reqwest 0.13 and rustls (no OpenSSL).
- One function per Web API method:
chat.postMessageisSlackClient::chat_post_message,conversations.historyisSlackClient::conversations_history, and so on. The full list is inapi. - Request and response types for every method, core objects in
objects, and typed Block Kit inblocks. - One shared connection pool (HTTP/2), a 30 second default timeout, optional retry on HTTP 429, cursor pagination and file upload.
This crate only calls the Web API. It does not receive events (Socket Mode, Events API, interactivity).
§Send a message
use slack_web_api::api::ChatPostMessageRequest;
use slack_web_api::SlackClient;
let client = SlackClient::new("xoxb-your-bot-token");
let res = client
.chat_post_message(&ChatPostMessageRequest::new("C0123456789").text("Hello from Rust"))
.await?;
println!("posted at {:?}", res.ts);Required arguments are the parameters of new; every optional argument is a method of the same name.
§Send a Block Kit message
use slack_web_api::api::ChatPostMessageRequest;
use slack_web_api::blocks::{ActionsBlock, Block, ButtonElement, HeaderBlock, SectionBlock, TextObject};
let blocks = vec![
Block::from(HeaderBlock::new(TextObject::plain("Deploy finished"))),
Block::from(SectionBlock::new().text(TextObject::mrkdwn("*api-server* is now on `v2.3.0`"))),
Block::from(ActionsBlock::new(vec![
ButtonElement::new(TextObject::plain("Open")).url("https://example.com").into(),
])),
];
client
.chat_post_message(&ChatPostMessageRequest::new("C0123456789").text("Deploy finished").blocks(blocks))
.await?;§Read channel history with pagination
use slack_web_api::api::ConversationsHistoryRequest;
let mut pages = client.pages(ConversationsHistoryRequest::new("C0123456789").limit(200));
while let Some(page) = pages.next_page().await {
for message in page?.messages {
println!("{:?}: {:?}", message.user, message.text);
}
}§Upload a file
files.upload was retired on 2025-11-12. SlackClient::upload_files runs its replacement
(files.getUploadURLExternal, the upload, then files.completeUploadExternal).
use slack_web_api::{FileUpload, UploadDestination};
client
.upload_files(
vec![FileUpload::new("report.csv", "date,count\n2026-10-01,42\n")],
UploadDestination::channel("C0123456789").initial_comment("Daily report"),
)
.await?;§Handle errors
use slack_web_api::api::ConversationsInfoRequest;
use slack_web_api::SlackError;
match client.conversations_info(&ConversationsInfoRequest::new("C0123456789")).await {
Ok(res) => println!("{:?}", res.channel.and_then(|c| c.name)),
Err(err) if err.api_error() == Some("channel_not_found") => println!("no such channel"),
Err(SlackError::RateLimited { retry_after }) => println!("still rate limited: {retry_after:?}"),
Err(err) => eprintln!("{err}"),
}§Share the client
SlackClient is cheap to clone and every clone shares one connection pool, so create it once.
To reuse your application’s reqwest::Client, or to change the retry count or base URL, use the builder:
use slack_web_api::SlackClient;
let http = reqwest::Client::new();
let client = SlackClient::builder().http_client(http).token("xoxb-...").max_retries(5).build();
// Apps installed in many workspaces can switch the token and keep the pool.
let other_workspace = client.with_token("xoxb-other-workspace");§Methods without types
SlackClient::call_raw calls any method by name with any parameters and returns the JSON as is.
§How requests and responses are handled
- Requests are sent as
application/x-www-form-urlencoded, which every method accepts. Lists of strings are sent comma-separated and objects (blocks, attachments) as JSON. - The built-in HTTP client has a 30 second request timeout and a 10 second connect timeout. A client
passed with
SlackClientBuilder::http_clientkeeps its own settings. - HTTP 429 is returned at once as
SlackError::RateLimitedwith itsRetry-After, because only the caller knows how long a request may wait. WithSlackClientBuilder::max_retriesthe client waits forRetry-Afterand resends. Other failures are never retried, so a message is never posted twice. - Response fields are all optional. Scalars are read leniently, because Slack sometimes returns the same field as a string in one place and a number in another; unknown fields are skipped.
Modules§
- api
- Request and response types for every Slack Web API method, and the
SlackClientfunction that calls each one. - blocks
- Slack Block Kit types (blocks, elements, composition objects), plus message attachments, views and message metadata.
- de
- Lenient deserializers used by the generated response types.
- objects
- Core Slack objects shared by many responses, inferred from the documented examples of every method.
Structs§
- File
Upload - A file to upload with
SlackClient::upload_files. - Pages
- Cursor pagination over a method. Created by
SlackClient::pages. - Response
Metadata - The
response_metadataof a response: the pagination cursor plus warning and error details. - Slack
ApiError - Details of an
"ok": falseresponse. - Slack
Client - Slack Web API client.
- Slack
Client Builder - Builder for
SlackClient. - Upload
Destination - Where uploaded files are shared. With nothing set, the files stay private and unshared.
Enums§
- Slack
Error - Error returned by a Web API call.
Traits§
- Cursor
Paginated - A request that supports cursor-based pagination.
- Next
Cursor - A response that carries the cursor for the next page.
- Slack
ApiMethod - A request for one Web API method. Implemented by every generated
*Requesttype.
Functions§
- as_json
serialize_withhelper that sends a list as a JSON array string instead of a comma-separated list. Used by arguments whose documented example looks like["C1","C2"].