Documentation 29
Slack API quickstart · 3 min read
The channels where the story gets discussed.
The Slack Web API — conversations, threads, reactions, and the workspace roster — for a simulated org whose chatter reconciles with everything else it does: the #incident-bridge burst brackets a real tracker incident, review threads echo real PRs, and release announcements cite tags you can fetch from the git hosts.
Coverage, hosts and pinned snapshots for Slack — 16 of 17 read surfaces served and verified.
01 / Base URL + auth
One workspace, any token.
Point requests at https://slack.sandboxapis.dev. Paths are Slack's method-RPC grammar — /api/<method>, exactly like slack.com/api — and the error model is Slack's own inversion: success and failure are HTTP 200, split by the body's ok boolean (the only real HTTP status in the dialect is the rate-limit 429 + Retry-After). Auth is a bot or user token (xoxb-…/xoxp-…) in the Bearer slot; any value passes here — no app to create, no scopes to request, no install flow.
curl -H 'Authorization: Bearer xoxb-anything' \
"https://slack.sandboxapis.dev/api/conversations.list"Using a key? Keys & rate limits → — a SandboxAPIs key rides the same Bearer slot and lifts the anonymous limit.
02 / The reads that matter
Channels, history, threads, people.
# The workspace's channels — one per team, plus #incident-bridge,
# #releases, and #agora (the org-wide square)
curl -H 'Authorization: Bearer xoxb-anything' "https://slack.sandboxapis.dev/api/conversations.list"
# A channel's history (newest first, cursor-paginated, top-level only)
curl -H 'Authorization: Bearer xoxb-anything' \
"https://slack.sandboxapis.dev/api/conversations.history?channel=CHANNEL_ID"
# A thread: the parent message first, then its replies
curl -H 'Authorization: Bearer xoxb-anything' \
"https://slack.sandboxapis.dev/api/conversations.replies?channel=CHANNEL_ID&ts=PARENT_TS"
# The roster — emails join against the AI-telemetry hosts' rosters
curl -H 'Authorization: Bearer xoxb-anything' "https://slack.sandboxapis.dev/api/users.list"03 / A real response
Live from #incident-bridge.
{
"ok": true,
"messages": [
{
"type": "message",
"user": "U127GRU2DLG",
"text": "schema marks a nullable field as required. paging whoever's closest to the logger.",
"ts": "1781455608.003359",
"team": "T3WXAQR47CB",
"thread_ts": "1781455608.003359",
"reply_count": 15,
"reply_users": [
"UNDH9MROOV9",
"UZ4CH940GQH",
"UOEW4UQN3I4",
"UM7D2RMLWY1",
"UJ4C66GKFQ6",
"U7YS3B38974",
"U127GRU2DLG",
"U592EZ56KGE",
"UMSMHBBLH8H",
"UQE80ZXP3UZ"
],
"reply_users_count": 10,
"latest_reply": "1781636928.664201",
"is_locked": false,
"subscribed": false
}
],
"has_more": false,
"pin_count": 0,
"response_metadata": {
"next_cursor": ""
}
}04 / Pin a snapshot
Deterministic CI.
The *.snap. base URL is byte-identical on every request — every ts, every thread, every reaction frozen — a messaging fixture that never moves under your tests.
# reproducible in CI
export SLACK_API_URL=https://slack-2026-08.snap.sandboxapis.dev/api/Tour the universe → · Coverage manifest → · Versioning & pinning →