How-to

Generate an SDK from OpenAPI in five minutes

The shortest path from an OpenAPI 3.x spec to a usable SDK is to skip the per-language templates and go straight to a generator that emits a typed client, error classes, and a runnable example in one pass. This post walks the five-minute version of that path using Bloom.

What you need

  • An OpenAPI 3.0 or 3.1 spec (yaml or json). Anything that validates in Spectral or the Swagger Editor is fine.
  • Optionally, a stainless.yml-style generator config. If you don't have one, Bloom will infer a starter from the spec.
  • About five minutes.

The five-minute walkthrough

1. Upload your spec

Open the Bloom dashboard, drop your openapi.yaml into the project upload zone. Bloom validates the spec, indexes operations and schemas, and infers a base URL from the servers block.

If the spec uses a servers: [...] list, the first entry becomes the default base URL. If not, the generated client will read <CLIENT>_BASE_URL from the environment at runtime.

2. Get the SDK preview

Click "Generate preview." Bloom emits two SDKs:

  • TypeScript: package.json, tsconfig.json, README.md, and src/index.ts. The client class is named after your config's organization.name (e.g. AcmeAPI).
  • Python: pyproject.toml, package files, sync and async client modules, error classes, and models. The package name comes from the config's targets.python.package_name.

Both packages are typed end-to-end: every operation has a matching method signature, every schema has a matching interface (TS) or pydantic model (Python).

3. Read the generation report

The report tells you exactly what was generated and what was skipped:

  • Methods: count of operations covered, plus any skipped (e.g. an operation in stainless.yml that isn't in the OpenAPI spec).
  • Resources: the resource tree, with sub-resources as nested namespaces.
  • Skipped methods: configured operations that have no OpenAPI source — usually a stale config that needs an update.

Anything skipped is a configuration drift to fix, not a bug.

4. Try the runnable snippet

Every Bloom-generated SDK ships with a README that has a copyable snippet using your config's example endpoint and parameters. For most messaging APIs the example looks roughly like this:

import AcmeAPI from "acme";

const client = new AcmeAPI({
  apiKey: process.env.ACME_API_API_KEY,
  apiSecret: process.env.ACME_API_API_SECRET,
});

await client.messages.send({
  number: "REPLACE_ME",
  from_number: "REPLACE_ME",
  content: "Hello from Bloom",
});
from acme_api import AcmeAPI

client = AcmeAPI()  # reads ACME_API_* from env
client.messages.send(
    number="REPLACE_ME",
    from_number="REPLACE_ME",
    content="Hello from Bloom",
)

The example uses your spec's example endpoint, so it isn't a generic stub.

5. Decide what to publish

The preview is downloadable. You can:

  • Hand it to a customer to test against an existing API.
  • Diff the public surface against your current SDK (Bloom's compatibility report does this automatically).
  • When ready, repo-sync to your SDK repos and let Bloom dry-run npm publish and pypi publish.

Nothing reaches a customer until you press publish.

How Bloom differs from raw openapi-generator

openapi-generator is excellent at the raw "spec to code" step. It is not a docs platform, not a release workflow, and not a migration report.

Bloom wraps SDK generation with the things teams end up needing anyway:

  • Hosted docs from the same spec (custom domain, llms.txt, redirects).
  • A compatibility report against your current SDK so the migration is reversible.
  • npm/PyPI publish dry runs before any package version goes out.
  • Examples that survive every regeneration because they come from the spec, not from hand-edited files.

If you only need raw codegen, the OpenAPI Generator templates are great. If you need the workflow around codegen, Bloom is a single tool instead of three.

Try it