Tutorials

Build a Typed Plaid API Client from Its OpenAPI Spec

Plaid publishes its full OpenAPI spec at plaid/plaid-openapi, a single ~3 MB YAML file covering the entire Plaid API. You can point a generator at it directly. Plaid already ships official, maintained SDKs for Node, Python, Java, Go, and Ruby — so this isn't about replacing plaid-node. It's for a language Plaid doesn't cover, an internal wrapper around a specific product (Auth, Transactions, Identity), or typed tool calls for an agent.

Where the spec lives

Fact Value
Repo plaid/plaid-openapi
File 2020-09-14.yml
Default branch master
Spec version OpenAPI 3.0.0, info.version: 2020-09-14_1.740.1
Size ~3.0 MB (YAML)
License None stated in the repo (no LICENSE file)

The filename (2020-09-14.yml) is Plaid's API version date, not a stale snapshot — Plaid still versions its API by date, and this file tracks the current one. The info.version field appends the underlying spec build number (_1.740.1) so you can tell when the file last changed even though the API-version date hasn't moved.

How to fetch it

curl -sL -o plaid-openapi.yml \
  https://raw.githubusercontent.com/plaid/plaid-openapi/master/2020-09-14.yml

Or clone the repo to get the changelog alongside it:

gh repo clone plaid/plaid-openapi

The honest complication: every operation shares one tag

Most OpenAPI generators split generated code into one class or module per tags value — that's how the GitHub and Stripe clients in this series end up with separate IssuesApi, ReposApi, CustomersApi, and so on. Plaid's spec doesn't give a generator that option. Checking directly:

grep -c "        - plaid" plaid-openapi.yml   # 352

All 352 operations across Auth, Transactions, Identity, Liabilities, Investments, Income, and every other Plaid product are tagged exactly one way: plaid. Run this through typescript-fetch or a similar tag-grouping generator and you get a single giant API class with 350-plus methods instead of one class per product. Practical effects:

  • Tree-shaking by product doesn't happen automatically — importing "the client" pulls in every method, typed or not.
  • Editor autocomplete on the generated class is a long flat list, not grouped by product the way Plaid's own docs are organized.
  • If you only integrate Auth and Transactions, you'll want to hand-filter the generated file (or the source spec, by operationId prefix) rather than relying on tag-based splitting.

There's no per-operation security override either — the whole spec relies on the top-level default (PLAID-CLIENT-ID and PLAID-SECRET as required header API keys), so authentication itself isn't the hard part. Organizing the output is.

Generate a TypeScript client locally

npx @openapitools/openapi-generator-cli generate \
  -i plaid-openapi.yml \
  -g typescript-fetch \
  -o ./generated/plaid-client

For types only, paired with your own request wrapper:

npx openapi-typescript plaid-openapi.yml -o ./src/plaid-api.d.ts

openapi-typescript sidesteps the single-tag problem entirely since it emits one flat type map rather than tag-grouped classes — often the better fit for a spec shaped like Plaid's. Run the file through the free OpenAPI validator first to confirm it parses cleanly before you spend generator time on it.

The hosted path

Sourced takes the Plaid OpenAPI file directly — paste the raw spec URL or connect your repo — and produces hosted docs, a TypeScript SDK preview, a Python SDK preview, and an llms.txt file in one pass, with docs organized by Plaid's actual product groupings rather than the spec's single flat tag. Previews are free and unlimited, with up to two hosted noindex docs sites and one hosted MCP server, no credit card required.

When this actually makes sense

  • A language Plaid doesn't officially cover. Plaid's SDK list is Node, Python, Java, Go, and Ruby — Rust, Kotlin, and other ecosystems have no official client.
  • Scoping a client to one product. If you only use Auth and Identity, a generated client lets you filter the spec down before generating instead of shipping the full surface.
  • Internal wrappers that need Plaid's types without plaid-node's specific retry, pagination, and webhook-handling opinions.
  • Agent tooling. A generated Plaid client, or an MCP server built from the spec, gives an LLM agent typed, discoverable tool calls against Plaid's API.

If you're writing a Node, Python, Java, Go, or Ruby app that talks to Plaid, use the official SDK for that language. It's maintained by Plaid and already handles webhook verification, Link token exchange, and error retry semantics — a generated client won't replicate that by default.

FAQ

Does Plaid have an official OpenAPI spec?

Yes. plaid/plaid-openapi is Plaid's own public repository, updated alongside API releases — not a third-party reconstruction.

Is the Plaid OpenAPI spec OpenAPI 3.0 or 3.1?

3.0.0. There's no 3.1 variant published in the repo as of this writing.

Why does my generated Plaid client have one enormous API class instead of several?

Every operation in the spec is tagged plaid and nothing else, so tag-grouping generators (like typescript-fetch) can't split the output by product. Use openapi-typescript for a flat type map instead, or filter the source spec by operationId prefix before generating.

Does the Plaid spec have a license?

The repository doesn't ship a LICENSE file. Treat the spec as Plaid's proprietary documentation of their own API rather than an openly licensed artifact, and check with Plaid directly if you need redistribution terms.

Should I generate a client instead of using Plaid's official SDK?

Not for Node, Python, Java, Go, or Ruby — the official SDKs handle webhook signature verification and Link flows correctly. Generate a client only for an uncovered language, a scoped internal wrapper, or agent tooling.

Can Sourced generate docs and an SDK from the Plaid spec directly?

Yes — point Sourced at the raw spec URL and it produces hosted docs, TypeScript and Python SDK previews, and an llms.txt file. Previews are free and unlimited; paid plans start when you're ready to publish under your own package name and domain.