ClaudeAPI integrationLevel 3: Workflows

How Do You Generate a Typed API Client With Claude?

If the API publishes an OpenAPI schema, generate the types with a tool, then have Claude write a thin client around them. If there's no schema, give Claude real response samples. If the vendor has an official SDK, use that first. Anthropic's come in Python, TypeScript, C#, Go, Java, PHP and Ruby.

Prompt to copy
I need a typed client for [API]. The types are generated in [path, such as src/api/schema.d.ts] from [path to schema]. Don't edit the generated file.

Write a thin client in [path] with one method for each of these endpoints only: [list].

- Follow the HTTP and error conventions in [an existing client file].
- Validate every response at the boundary with [Zod / Pydantic], and throw an error naming the endpoint and the field when it doesn't match.
- Set an explicit timeout on each request.
- Use only endpoints and fields in the schema. If something I need is missing, tell me instead of inventing it.

Then run `[typecheck command]` and the tests, and show me the output.
  1. 1Schema or real response samplesthe source of truth
  2. 2Generated typesa tool, not the model
  3. 3Thin clientClaude writes this
  4. 4Validator at the boundarychecks what really arrives
A rule of thumb, not a vendor chart: let a tool write the types and Claude write the thin layers around them.

Try it now

  1. 1For a TypeScript project, run npm i -D openapi-typescript typescript, then the npx openapi-typescript command above with your schema's path.
  2. 2Paste the prompt into Claude Code with your generated types and two or three endpoints.
  3. 3Add Edit(src/gen/**) to permissions.deny in .claude/settings.json, using your own folder, so Claude's file tools can't hand-edit generated code.
  4. 4Rename a field in a copy of the schema, regenerate, and run your typecheck. It worked if the build fails at the exact call sites using that field.

Use it when

A third-party or internal API you'll call from several places, especially one with a published schema. Also when changing response shapes keep surprising your code.

Skip it when

A single one-off call. Also the Claude API itself: Anthropic's SDKs already give you typed responses, retries, streaming and error handling, so a generated client means maintaining what you'd get for free. If an API's real responses often don't match its schema, start with the validator, because generated types would give false confidence.

Why it works

A generator copies the schema exactly, while a model can drift on a long file. npx openapi-typescript ./path/to/my/schema.yaml -o ./path/to/my/schema.d.ts produces what its docs call runtime-free types from OpenAPI 3.0 or 3.1. That's also the catch: the types describe what should arrive, and nothing checks what does. Claude can fill that gap by adding a validator at the boundary, such as Zod, whose .parse() throws a ZodError on a mismatch. Size matters in Claude Code too. One read returns up to 25,000 tokens by default, and a whole file over 256KB is refused, so a big spec arrives in pages. Name the endpoints you need rather than asking for the whole API.

Example

Say a payments provider publishes openapi.yaml. You generate the types and ask for createCharge() and refund() only, with responses checked by a Zod schema through Charge.parse(body). Suppose the vendor later renames a field. Before you regenerate, the validator throws an error naming that field at the boundary, so nothing passes undefined downstream. After you regenerate, your build fails at each call site that uses the old name, and you fix those.

Going further

When you want typed JSON from Claude itself, use structured outputs: output_config.format in the API, or client.messages.parse() with Pydantic, or with Zod through zodOutputFormat(). The schema has limits. additionalProperties must be false, and minimum, maximum, minLength, maxLength and recursive schemas aren't supported, so they return a 400. A stop_reason of refusal or max_tokens can still produce output that doesn't match, so check it before you parse. The older trick of forcing a tool to get JSON also fails now: tool_choice of any or tool returns a 400 on Opus 5.5, Sonnet 5.5 and Fable 5.1.

Common mistakes

  • Having Claude transcribe a long schema into types by hand, when a generator would copy it exactly.
  • Trusting generated types at runtime. They compile away, so a changed response passes straight through.
  • Asking Claude to wrap the whole spec. Name the endpoints you use, and add more when you need them.
  • Hand-editing a generated file, which the next generation run overwrites. Note that the deny rule doesn't stop a script that writes files itself.

Sources

Checked 6 November 2026. Products change often, so confirm details with the vendor.

Related

Beyond the course