Founding keys are opena year free at 6,000 req/hour, for the first 1,000 developersClaim yours

Slack

Point @slack/web-api (or curl) at https://slack.sandboxapis.dev via the client's slackApiUrl option (paths are /api/<method>, exactly like slack.com/api). Auth is a Bearer bot/user token (xoxb-…/xoxp-… — any value is accepted here). This is the org's team-messaging surface: channels, history, threads, reactions, and the workspace roster — the SAME story the git hosts and trackers tell, discussed. The #incident-bridge channel's burst brackets the real incident issue; #releases announcements cite real tags. Success and failure are BOTH HTTP 200 with an ok boolean — Slack's real error model.

REST · 22 endpointsMCP-ready

Coverage badge

Deep16/17 · 94%

The share of read rows with a final answer — served and verified, a deviation, retired upstream, or a reviewed empty/refusal. Computed in the coverage manifest, copied here.

Live host
slack.sandboxapis.dev
Pinned hosts
5 — generation 6, 8, 9, 10, 11
Serving since
2026-08-25
Lifecycle
Live

Served & verified

16 / 94%

Answering with real universe data, each response checked against Slack's published spec by the conformance suite on this build.

The full read API

17

Every read surface Slack publishes, deferred long tail included, minus the rows excluded by policy (5). Writes are out of scope: this universe is read-only.

Not served yet

1

Each returns an explicit, provider-shaped coverage error naming the gap — never invented data.

01 / The swap

Point your client at a different base URL.

No SDK of ours, no shim, no recorded fixtures. The same client library you already use, one environment variable different.

shell
curl -H 'Authorization: Bearer xoxb-anything' "https://slack.sandboxapis.dev/api/conversations.list"

Verified drop-in clients

  • @slack/web-api7.19.0

The versions the conformance suite drives against this host on every build — pinned in coverage/client-pins.yaml, and watched weekly for upstream releases, because a client library moving without us is how a shipped integration breaks silently.

This spec is hand-authored, and that is a weaker guarantee.

Slack publishes no machine-readable API description, so the spec we conform to is written from their documentation plus live captures (retrieved 2026-08-25) and re-diffed against those pages on a schedule. Where a vendored spec makes conformance a mechanical check, this one is only as good as our reading of the docs — which is why it is stated here rather than buried in the manifest.

Spec of record: docs.slack.dev method docs (no living machine-readable spec — hand-authored shape-of-record) + live captures 2026-08-25

02 / Coverage by family

Every read surface, grouped the way Slack groups it.

All 22 rows the coverage manifest carries for Slack, deferred long tail included and nothing capped. Open a family, or filter by path to find the exact endpoint your client calls.

Status — what a conformance test found

served & verified
answers with real universe data, and this build checked that response against the vendor's spec.
deviation
served and faithful to the real provider, but failing the vendored spec — usually a bug in the spec.
retired
the vendor removed the endpoint; snapshots pinned before that date still serve it.
planned / deferred
not served yet — an explicit coverage error naming the gap, never invented data.
excluded
out of the claim by policy (writes, and surfaces we refuse); not in any denominator on this page.

Mode — what kind of answer a row gets

derive
the response is computed from artifact rows that already exist
generate
canon does not carry this yet; the generator will produce it, then derive
empty
the true answer for this universe is an empty collection — reason + reviewed date required
refuse
mirror the provider's OWN refusal (e.g. its 403 for a non-admin token) — reason + reviewed date required
read-only
a write named in the manifest because clients probe it; the read-only 403 IS its final response, and it never joins the badge denominator

A row with no mode shown has not been judged yet. Modes are the manifest's own words, from coverage/MODES.yaml; every empty and refuse carries a written reason and a review date before it counts as final.

Badge — where Deep starts

Full
every published read row has a final answer
Deep
60% up to 100%
Partial
25% up to 60%
Preview
under 25%

REST + GraphQL + git rows that are not `excluded`. Write operations are NOT rows (DECISIONS 2026-09-01 decision 9): they are counted in meta.write_operations and never enter this ratio.

22 read surfaces in 16 families

conversations5 of 5 served & verified
GET
/api/conversations.history
served & verified
Core
GET
/api/conversations.info
served & verified
Core
GET
/api/conversations.list
served & verified
Core
GET
/api/conversations.members
served & verified
Core
GET
/api/conversations.replies
served & verified
Core
users3 of 3 served & verified
GET
/api/users.info
served & verified
Core
GET
/api/users.list
served & verified
Core
GET
/api/users.lookupByEmail
served & verified
Core
admin0 of 1 served & verified
GET
/api/admin.conversations.search
excluded
Long tail
app-auth0 of 1 served & verified
GET
/api/oauth.v2.access
excluded
Long tail
auth1 of 1 served & verified
POST
/api/auth.test
served & verified
Core
bookmarks0 of 1 served & verified
GET
/api/bookmarks.list

generate — new canon entity Bookmark

deferred
Next
emoji1 of 1 served & verified
GET
/api/emoji.list

this workspace has no CUSTOM emoji — the canon's reaction emoji are the standard set, which real Slack never lists here (DECISIONS 2026-08-25 [P34/slack] item 6)

served & verified
Core
files1 of 1 served & verified
GET
/api/files.list

no message in this universe carries a file — `message` has no attachment column and the fleet's only file entity, `attachment`, hangs off the support desk's ticket comments and macros and - from hello-18's attachmentParents - issues, issue comments, merge requests, alerts and the namespace, never off a chat message (clause re-worded at the hello-18 cutover 2026-09-12: the canon grew, the conclusion did not move); Slack's own answer for a workspace with no files is {ok:true, files:[], paging:{...}} at 200. RULED by the founder 2026-09-12 (round 19), coverage wave W5. It is already the third statement of one fact on this host: reactions.get refuses a `file` argument with file_not_found, and files.upload is a write

served & verified
Next
pins1 of 1 served & verified
GET
/api/pins.list

no message in this workspace is pinned, on any channel — which is what keeps conversations.history's pin_count: 0 coherent (DECISIONS 2026-08-25 [P34/slack] item 6)

served & verified
Core
presence0 of 1 served & verified
GET
/api/users.getPresence
excluded
Long tail
reactions1 of 1 served & verified
GET
/api/reactions.get
served & verified
Core
rtm0 of 1 served & verified
GET
/api/rtm.connect
excluded
Long tail
search1 of 1 served & verified
GET
/api/search.messages

SERVED (wave W5) by a BOUNDED message search over the messaging canon — the soql.ts/sosl.ts contract in a third grammar: every modifier outside the subset is refused BY NAME with the coverage headers inside Slack's ok:false envelope, never ignored, because a search that quietly drops `has:link` returns MORE matches than the caller asked for and looks exactly like a correct answer. COVERED: bare terms (all must match, on whole-word tokens), quoted phrases, `in:` by name or id, `from:` by login, id or <@U…>, count/page with the doc's own 100 ceilings, sort=timestamp and sort_dir. REFUSED BY NAME: every other modifier, `-negation`, explicit AND/OR, wildcards, `highlight=true` and cursormark pagination. `sort=score` is NOT refused even though this replica computes no relevance — it is the default, refusing it would refuse every naive call, and the SET and the counts are exact while Slack's match objects carry no score field for us to invent a value for; the order served is the documented newest-first. One narrowing is stated rather than hidden: this replica matches message TEXT only, where the doc says users and channels also match at a lower priority — narrower than the real API, never wider. Matches come from BOTH halves of a channel's history, top-level and thread replies, because this canon puts the detail in the threads

served & verified
Next
stars0 of 1 served & verified
GET
/api/stars.list
excluded
Long tail
team1 of 1 served & verified
GET
/api/team.info
served & verified
Core
usergroups1 of 1 served & verified
GET
/api/usergroups.list
served & verified
Core

03 / What's simulated

One data set, rendered in Slack's dialect.

Every Slack call resolves against the same simulated data set every other provider serves. Counted from the slack-2026-08-g11 artifact (universe generation 11):

What another provider has to agree with, and the test that makes it

Each line below is one assertion in the conformance suite named beside it — run on every build, over one artifact, through the real renderers. Nothing is claimed here that no expect checks.

05 / Pinned snapshots

Frozen universes, on their own hostnames.

Each pin regenerates byte-identically on every request, so a test written against one never drifts. Generations are DIFFERENT universes, not versions of one — never swap a suffix expecting the same data.

PinHostUniverse generationSlack API versionRepository files
slack-2026-08slack-2026-08.snap.sandboxapis.devgeneration 6unversionedserved
slack-2026-08-g10slack-2026-08-g10.snap.sandboxapis.devgeneration 10unversionedserved
slack-2026-08-g11slack-2026-08-g11.snap.sandboxapis.devgeneration 11unversionedserved
slack-2026-08-g8slack-2026-08-g8.snap.sandboxapis.devgeneration 8unversionedserved
slack-2026-08-g9slack-2026-08-g9.snap.sandboxapis.devgeneration 9unversionedserved

Need an endpoint that is not served yet?

Every row Slack's manifest carries is on this page, so “not here” is an answer rather than a gap in the rendering. Tell us which path and which client, and it moves up the queue — the order is set by what people ask for.

Request coverage