Slack killed their OpenAPI spec, so we built one from their TypeScript SDK
272 endpoints, 134 webhooks, zero web scraping — generated from the TypeScript AST
We’re building Strata, a tool that lets you connect software providers and plumb data between them. Under the hood, Strata’s AI agents rely on OpenAPI schemas to understand what each provider can do — what API endpoints are available, what the request/response shapes look like, and which webhooks you can subscribe to. These agents allow even non-technical users to quickly (and most importantly, accurately) connect various service providers and translate fields between them.
This works great for providers that publish Swagger/OpenAPI specs. Unfortunately, Slack happens to be amongst those that don’t.
Just here for the spec? Grab it directly: slack-openapi-spec.json — 272 endpoints, 134 webhooks, 1,526 schemas, updated weekly.
Or, play around with it, directly in your browser, in Swagger’s online editor.
The problem
In 2024, Slack officially “terminated” their public OpenAPI specification. If you go looking for one now, you’ll find a graveyard of stale community specs, half-working scrapers, and specs that silently drop fields because Slack’s API types are genuinely complex — intersection types, literal string discriminators, deeply nested unions, dynamic RPC payloads.
We needed a complete, accurate spec for Strata’s Slack integration. Nothing we found was complete and up-to-date. So we built a generator!
The approach: read the source of truth
Here’s the key insight: Slack may have abandoned their OpenAPI spec, but their official Node SDK (@slack/web-api, @slack/bolt, @slack/types) is actively maintained and meticulously typed. The TypeScript type definitions are the spec — they’re just in an inconvenient format.
So rather than scraping docs or reverse-engineering API responses, the generator uses ts-morph to parse the Abstract Syntax Tree of the SDK’s TypeScript declarations and transpile them into OpenAPI 3.1.0.
No web scraping. No API calls. No guessing. Just reading the types (and docs!) that Slack’s own engineers maintain.
How it works under the hood
The generator runs through a few stages:
1. Load the SDK’s type declarations. ts-morph ingests all the .d.ts files from the three Slack packages into an in-memory AST with strict null checks enabled.
2. Walk the Methods class. The SDK declares every API endpoint as a nested property on a Methods class. The generator recursively walks this tree — each leaf is typed as MethodWithRequiredArgument<Args, Response> or MethodWithOptionalArgument<Args, Response>, so extracting the request and response types is straightforward. Property paths map directly to endpoint names: files.uploadV2 becomes /api/files.uploadV2.
3. Convert TypeScript types to OpenAPI schemas. This is the hard part. The type mapper handles:
Unions →
anyOf, with optimizations like collapsing string literal unions into a singleenumand hoisting common properties across branchesIntersections →
allOf, with inline object squashing so you don’t get needlessly nested schemasGenerics → resolved by following defaults and constraints
Circular references → broken with placeholder schemas and lazy thunks
Name collisions → when two packages export a type with the same name (e.g., Bolt’s
Authorizationvs. web-api’sAuthorization), the registry auto-disambiguates with numbered variants
4. Extract webhooks. Interfaces ending in Event, Action, or Shortcut from Bolt’s type definitions become webhook schemas, wrapped in the standard EnvelopedEvent envelope.
5. Detect binary fields. The generator recursively scans schemas for format: "binary" and automatically adds multipart/form-data as a content type for those endpoints — so file upload endpoints Just Work.
Staying up to date
A schema is only useful if it’s current. A GitHub Action runs weekly: it installs the latest versions of all three Slack packages, regenerates the spec, and auto-commits if anything changed. No manual maintenance required.
Why we open-sourced it
We built this for Strata, but there’s no reason to keep it proprietary. We’ve pulled numerous community-maintained OpenAPI specs for use in our product, and we’d love to be a good neighbor and return the favor.
Anyone building Slack integrations — whether you’re generating client SDKs, feeding API context to LLMs, setting up Postman collections, or building documentation — can use the generated spec directly.
You can grab the latest spec from the repo: slack-openapi-spec.json
Or clone the repo and generate it yourself:
git clone https://github.com/connectstrata/slack-openapi-generator.git
cd slack-openapi-generator
npm install
node generate.jsWhat’s next
If you use the spec and run into edge cases — missing endpoints, type inaccuracies, TypeScript patterns that aren’t handled — we’d love to hear about it. Open an issue or submit a PR.
And if the idea of connecting APIs without writing glue code sounds interesting, check out Strata — it’s the project that started all of this.
