SDK generation
How to generate type-safe clients from the OpenAPI specs. Per-language generator recommendations + gotchas.
YieldFabric ships OpenAPI specs, not SDKs. SDKs are auto-generated from the specs using whatever tool fits your language. This page lists the recommended generators and the gotchas for each.
Why no first-party SDKs?
Generating SDKs is a maintenance burden that scales with language
count × spec complexity × release cadence. Three services × 4-5
target languages × the change rate documented in
versioning.md is more than a doc team can
sustainably maintain.
Instead, the specs are SDK-generator-friendly:
- OpenAPI 3.1 (not Swagger 2 or OpenAPI 3.0). Modern tools consume this natively.
- JSON Schema 2020-12 in
components/schemas/(OpenAPI 3.1's native schema dialect). No conversion step. - Operations have
operationIdconsistently across all three services. Generators use this for method naming. - Tags are domain-organised (
Auth,Groups,Payments,Workflows, etc.). Generators use tags to group methods into classes. - Path shards / per-operation YAMLs all
$reffrom one rootopenapi.yaml. Bundle once, generate many.
Recommended generators
openapi-fetch for the runtime.Step 1 — Bundle the spec
The platform serves a pre-bundled spec for each service from the docs site. Download the JSON for the services you need:
curl -o /tmp/auth-bundled.json https://yieldfabric.com/api/openapi/auth.json
curl -o /tmp/payments-bundled.json https://yieldfabric.com/api/openapi/payments.json
curl -o /tmp/agents-bundled.json https://yieldfabric.com/api/openapi/agents.json
The bundled file is what you hand to the generator.
Step 2 — Generate
TypeScript (type-only, recommended)
npx openapi-typescript /tmp/auth-bundled.json -o auth-types.ts
npx openapi-typescript /tmp/payments-bundled.json -o payments-types.ts
npx openapi-typescript /tmp/agents-bundled.json -o agents-types.ts
Pair with openapi-fetch for typed fetch() calls:
import createClient from "openapi-fetch";
import type { paths } from "./auth-types";
const auth = createClient<paths>({ baseUrl: "https://auth.yieldfabric.com" });
const { data, error } = await auth.POST("/auth/login", {
body: { email: "user@example.com", password: "…" }
});
Python
pip install openapi-python-client
openapi-python-client generate --path /tmp/auth-bundled.json
Generates a fully-typed Python client in the current directory.
Rust
progenitor::generate_api!("auth-bundled.yaml");
let client = Client::new("https://auth.yieldfabric.com");
let response = client.login(&LoginInput { email, password }).await?;
Step 3 — Wire authentication
All three services use HS256 JWT in Authorization: Bearer <token>.
The OpenAPI spec declares this in components/securitySchemes.yaml,
so generators emit auth helpers automatically — but you'll need to:
- Call the login endpoint to get the token (auth service's
POST /auth/loginis the canonical path). - Stash the token + refresh token.
- Refresh on
401 TOKEN_EXPIREDviaPOST /auth/refresh.
For TypeScript with openapi-fetch:
const auth = createClient<paths>({
baseUrl,
headers: { Authorization: `Bearer ${token}` }
});
For Python: most generators provide a set_authorization(token)
helper or accept the header in the client constructor.
Step 4 — Handle errors
{ "error": "<string>" }. Route on HTTP status, not body.errors[].extensions.code in the envelope. REST endpoints use the same flat shape as auth.Per-service catalogues:
- auth errors
- payments errors
- agents errors
Most generators wrap errors into typed exceptions; check the matching error model in your generated client.
Step 5 — Pin versions
Pin the spec hash you generated from. When the spec ships a new version:
- Re-bundle.
- Re-generate.
- Run your test suite against the new types.
- Fix any breaking compile errors (minor bumps shouldn't break; if they do, it's a spec-side regression — file an issue).
See versioning.md for the bump rules.
Gotchas per generator
openapi-typescript
- Type-only. You still need a runtime (
openapi-fetchrecommended). - Outputs one big
pathstype tree. Smart-imports work fine. - Doesn't handle
additionalProperties: trueperfectly — fields spread into[key: string]: unknown.
openapi-python-client
- Doesn't handle
oneOfdiscriminators perfectly when the discriminator field is itself optional. The authClaimsKindschema works fine; others may need post-processing. - Generates models with
Unsetsentinels for optional fields, which can surprise newcomers — read the project's README first.
progenitor
- Handles OpenAPI 3.0 + 3.1; some 3.1-specific features (e.g.
nullin type unions) need workarounds. - Async-only output. If you need a blocking client, wrap with
tokio::runtime::Runtime::block_on.
openapi-generator
- Multi-language. Java + Kotlin output is mature; some other languages lag.
- Doesn't always handle
$refchains cleanly — bundle first.
Federated GraphQL: no SDK generation
The federated gateway at api.yieldfabric.com/graphql is a GraphQL endpoint. SDK
generators are OpenAPI-only; they won't process the GraphQL schema.
For GraphQL clients, use:
graphql-request (minimal) or urql / apollo-client (full)gqlcynic (type-safe) or graphql-clientGenerate GraphQL types from the federated gateway schema at
https://api.yieldfabric.com/graphql, or from checked-in client
operations if your client generator supports operation-first typing.
Webhook / SSE clients
Neither OpenAPI generators nor GraphQL clients handle the SSE event
streams documented in webhooks-and-events.md.
For those, use a plain SSE client per language:
EventSource (browser) or eventsource (Node)sseclient-pyreqwest-eventsourceFuture: first-party SDKs
If/when SDKs ship as first-party, this page will be replaced with links to npm / PyPI / crates.io packages. The OpenAPI specs will keep working as input for anyone generating their own.
See also
webhooks-and-events.md— what SDK generators can't help with.versioning.md— when to re-generate.-
Per-service quickstart guides: