You can generate the client from an OpenAPI spec. The part you still own is deciding what callers can rely on: method names, authentication, error handling, and compatibility from one release to the next.
This walkthrough generates a TypeScript Fetch client from a small sample OpenAPI spec and runs a smoke test without hitting a live API. The same spec can feed your API reference generator.
1. Give the generator a stable contract
Download the sample as openapi.yaml. It defines GET /webhooks/{id}, a stable getWebhook operation ID, bearer auth, and a typed success response. Before generating from your real spec, check that operations have meaningful IDs and that required fields, auth, and errors match what the API actually returns.
2. Generate the TypeScript client
Install the OpenAPI Generator CLI and use version 7.13.0 to reproduce this example. In a scratch project with Node.js 22 and TypeScript installed:
1openapi-generator-cli validate -i openapi.yaml2openapi-generator-cli generate -i openapi.yaml -g typescript-fetch -o generatedThe typescript-fetch generator creates typed operations and a Fetch runtime. Keep generated files separate from hand-written code so you can regenerate them cleanly.
3. Smoke-test the generated client
Save this as smoke.ts next to the generated directory. The fake Fetch response keeps the test offline, but the generated client still builds the real URL and authorization header.
1import assert from "node:assert/strict";2import { Configuration, ResponseError, WebhooksApi } from "./generated";3
4async function main() {5 const api = new WebhooksApi(new Configuration({6 basePath: "https://api.example.com",7 accessToken: "test-token",8 fetchApi: async (url, init) => {9 assert.equal(init?.method, "GET");10 assert.equal(new Headers(init?.headers).get("authorization"), "Bearer test-token");11 if (url === "https://api.example.com/webhooks/missing") {12 return new Response(null, { status: 404 });13 }14 assert.equal(url, "https://api.example.com/webhooks/hook_123");15 return Response.json({ id: "hook_123", status: "active" });16 },17 }));18
19 assert.deepEqual(await api.getWebhook({ id: "hook_123" }), {20 id: "hook_123",21 status: "active",22 });23 await assert.rejects(24 () => api.getWebhook({ id: "missing" }),25 (error) => error instanceof ResponseError && error.response.status === 404,26 );27}28
29main().catch((error) => {30 console.error(error);31 process.exitCode = 1;32});From the scratch project, install TypeScript and Node types if needed, then compile and run the test:
1npm install --save-dev typescript@5.9.3 @types/node@222npx tsc smoke.ts --module node16 --target es2022 --strict --outDir dist3node dist/smoke.jsThis verifies the client against a fixture, not the live contract. Before releasing, also run a smoke test against staging with a real credential from the environment, including a documented error. Do not ship a server-side API token in a browser bundle.
4. Make regeneration part of release review
Pin the generator and commit its configuration. When the spec changes, regenerate into a clean directory and review the diff before publishing. A renamed operation ID can break callers even when the HTTP route is unchanged. Test the package as a consumer would install it, document breaking changes, and release it with a version and changelog.
Use the API docs sync guide to keep the reference and quickstart aligned with the SDK. For a quick check of what the same contract looks like to a reader, try the OpenAPI to Markdown tool.