Skip to content
SDK generatorOpen source · MIT

The open source, agent friendly client for generating SDKs, CLIs, docs, and more from your OpenAPI description

One command. One self-contained file. Zero dependencies.
TypeScript, Python, Go, or PHP - regenerate whenever your API changes.

⚗️ Experimental - flags and output may still change. Feedback welcome.

Explore docs
$ npx @redocly/cli@latest generate-client openapi.yaml --output src/client.ts
# → src/client.ts - every operation typed, zero dependencies
import { client, listMenuItems, getOrderById } from './client.ts';
​
client.auth.bearer(token);
const menu = await listMenuItems({ query: { limit: 10 } });
const order = await client.getOrderById({ path: { orderId: 'ord_01khr…' } });

1

command, description to client

0

runtime dependencies

4

languages - TS, Python, Go, PHP

100%

typed - bad calls fail the build

Your API description. A complete SDK

Type-safe by design

Every operation, parameter, and response typed from your description. A bad call fails the build, not production - add zod to catch contract breaks at runtime too.

Production-ready out of the box

Auth from securitySchemes, retries with backoff, typed pagination and SSE streaming, multipart uploads, composable middleware. Nothing to hand-write.

Built for your codebase

Single file or split. Flat or grouped arguments. Throw or typed results. Bake your defaults in with --setup and regenerate reference docs with --docs.

Runs anywhere

OpenAPI 3.0-3.2 or Swagger 2.0 in; TypeScript, Python, Go, or PHP out. Browsers, Node, Bun, Deno, edge - anywhere fetch does.

Delete the boilerplate

Types alone don't send requests - the client should ship the behavior too.

// Before: types-only generator - you still write all of this
const url = `${BASE}/orders/${encodeURIComponent(orderId)}`;
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
signal,
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const order = (await res.json()) as Order;
// After: generate-client - typed, authed, retried, cancellable
const order = await getOrderById({ path: { orderId } }, { signal });

Give your agent a client, not a blank editor

Generated code is the cheapest, safest code an AI can ship. One command, the same client every time - the AI-written part of your diff shrinks to intent.

Agents generate it

One tool call replaces ~12,000 tokens of hand-written HTTP plumbing. Deterministic output: nothing lands in review except your logic.

Agents code against it

A hallucinated endpoint or invented field fails the build, not production - the compiler is the agent’s fact-checker. Add zod for the same guardrail at runtime.

Agents test with it

--generator mock emits mocks and seeded factories, so AI-written tests run offline and reproduce exactly.

Put it in your agents file

Tell your coding agent once, in AGENTS.md or CLAUDE.md, and it stops hand-writing fetch code for good.

Publishing an SDK? Pair this with --setup: agents consume your API with your auth, retries, and headers baked in. Nothing to misconfigure.

API clients
## API clients
Never hand-write fetch/HTTP code for our APIs.
Regenerate the typed client from the OpenAPI description instead:
npx @redocly/cli generate-client openapi.yaml -o src/api/client.ts
Import the generated functions. A wrong call fails the build -
run the typecheck after changes instead of testing by hand.

A real example,
straight from the repo

This is our zero-install-quickstart example, unedited - client.ts was generated from openapi.yaml by one command. Tweak main.ts and hit Run: it calls the live cafe demo API from your browser.

// zero-install-quickstart — the whole loop: generate → import → call.
//
// `redocly generate-client` turned openapi.yaml into ONE self-contained file
// (src/api/client.ts) with zero runtime dependencies — there is no client
// library to install or keep in sync. Import the generated functions and call.
import { getMenuItemPhoto, listMenuItems } from './api/client.js';

const menu = await listMenuItems({ query: { limit: 3 } });
for (const item of menu.items) {
  console.log(`${item.name} — $${(item.price / 100).toFixed(2)}`);
}

const [first] = menu.items;
if (first) {
  const photo = await getMenuItemPhoto({
    path: { menuItemId: first.id },
    query: { photoSize: 'thumbnail' },
  });
  console.log(
    photo instanceof Blob ? `${first.name} photo: ${photo.type}, ${photo.size} bytes` : photo
  );
}
live request to api.cafe.redocly.com
// hit Run - main.ts executes right here
Get the example on GitHub

Generation is free. Running SDKs is the product

generate-client stays open source and ungated. For teams that publish SDKs, we’re building the pipeline, policy, and visibility around it in Reunite.

How does your company run SDKs?

Capability
Open source · today
SDK pipeline in Reunite Early access
Generate
Typed SDKs in TS, Python, Go, PHP, plus CLI, mocks, and docs. Free, forever.
Same generators, run as a pipeline with history and an audit trail
SDK readiness
Lint rules you configure
Readiness scorecard: your OpenAPI description passes SDK checks before anything ships
Preview builds
Regenerate locally and diff the output
A preview of every SDK and CLI for each change, before it merges
Release tests
Your own integration tests
Workflow tests (Arazzo) run with the generated SDK against staging as a publish gate
Publish
You version and publish each package
Autopublish: version from the OpenAPI diff, release when the gates pass
API versioning
One client per API version, maintained by hand
A client per major version, published side by side; existing SDKs keep working
Docs
--docs regenerates with the code
Snippets pinned to the released SDK version; SDK and docs ship in one PR
Contract drift
Runtime validation warns in the client
Drift telemetry compares SDK calls with the live API and opens an issue per mismatch
Deprecation
Search your codebase and ask around
Usage by operation and SDK version; deprecate with impact analysis

Add generators with one flag

Each emits its own file - the client stays dependency-free.

typescript(default)
Emits:the typed fetch client
For:calling your API from TypeScript
python · go · php
Emits:a full SDK, one self-contained file
For:the same client from any stack
tanstack-query
Emits:TanStack Query v5 factories
For:React / Vue / Svelte / Solid
transformers
Emits:Date converters
For:wire ISO strings → Date
swr
Emits:SWR hooks
For:React data fetching
zod
Emits:Zod schemas + zodValidation middleware
For:runtime contract checks
mock
Emits:MSW handlers + factories
For:tests & demos (baked or faker, seedable)
cli
Emits:a bin-ready CLI with typed flags, --dry-run, and documented exit codes
For:scripts, CI, and agents: schema prints any operation’s contract as JSON
your generator
Emits:anything, with its own docs page and code samples
For:the long tail - validators, facades, house-style SDKs
$ npx @redocly/cli@latest generate-client openapi.yaml -o src/client.ts \
--generator python --generator zod --generator cli --generator mock --docs

Docs that never drift

--docs writes a reference page for every generator you select, rendered from the same table the code runs on. codeSamples: true adds an x-codeSamples overlay, so every operation in your Redoc docs shows a snippet that agrees with the SDK.

Own the generator, not a fork

Eject any generator as TypeScript you own. Unmodified, it produces the exact same output, while upstream fixes still merge seamlessly.

Aspect
fork(the old way)
eject-generator
You getthe whole project, to maintain foreverone readable file per stage, in your repo
Upstream fixes arrive viastop reaching you--update
The design ships assource code you reverse-engineerSKILL.md
Your agent editsthe generated output, by handthe generator, never the output
Best fornobody - a fork is a life sentencehouse rules - naming, headers, error style (byte-identical until you change it)

Open source, in the CLI you already know

generate-client ships inside the MIT-licensed Redocly CLI - the same tool that lints and bundles your OpenAPI. No account, no server: it runs on your machine and the code is yours. Redocly’s own apps call our production APIs through clients generated by this exact command.

MIT

license - use it anywhere

0

accounts or sign-ups required

Which language should we add next?

TypeScript, Python, Go, and PHP today. Vote for the next one with a one-click issue.

Frequently asked questions

A typed client for your API - TypeScript by default, or Python, Go, PHP - in one self-contained file: types, per-operation functions, auth, retries, pagination, middleware. Generated from OpenAPI 3.x or Swagger 2.0. Add-ons: Zod validation, query hooks, mocks, a CLI, and docs.

Your typed client is one command away

One self-contained, zero-dependency file in TypeScript, Python, Go, or PHP. Open source. No account.

$ npx @redocly/cli@latest generate-client openapi.yaml --output src/client.ts