SDK generation

How to generate type-safe clients from the OpenAPI specs. Per-language generator recommendations + gotchas.

Guides/Integration

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 operationId consistently 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 $ref from one root openapi.yaml. Bundle once, generate many.
Language
TypeScript
Notes
Type-only output; pair with openapi-fetch for the runtime.
Language
TypeScript (full SDK)
Notes
Generates a full class-based SDK. Heavier output.
Language
Python
Notes
Active, well-maintained, supports OpenAPI 3.1.
Language
Rust
Generator
Notes
Type-safe, hyper-based. Maintained by Oxide.
Language
Go
Generator
Notes
Stable; pairs with chi or gin.
Language
Java / Kotlin
Notes
Multi-language generator; mature Java/Kotlin output.

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

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:

  1. Call the login endpoint to get the token (auth service's POST /auth/login is the canonical path).
  2. Stash the token + refresh token.
  3. Refresh on 401 TOKEN_EXPIRED via POST /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

Service
auth
Wire shape
Flat: { "error": "<string>" }. Route on HTTP status, not body.
Service
payments
Wire shape
GraphQL: HTTP 200 + errors[].extensions.code in the envelope. REST endpoints use the same flat shape as auth.
Service
agents
Wire shape
GraphQL same as payments. REST same 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:

  1. Re-bundle.
  2. Re-generate.
  3. Run your test suite against the new types.
  4. 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-fetch recommended).
  • Outputs one big paths type tree. Smart-imports work fine.
  • Doesn't handle additionalProperties: true perfectly — fields spread into [key: string]: unknown.

openapi-python-client

  • Doesn't handle oneOf discriminators perfectly when the discriminator field is itself optional. The auth ClaimsKind schema works fine; others may need post-processing.
  • Generates models with Unset sentinels 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. null in 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 $ref chains 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:

Language
TypeScript
Client
graphql-request (minimal) or urql / apollo-client (full)
Language
Python
Client
gql
Language
Rust
Client
cynic (type-safe) or graphql-client

Generate 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:

Language
TypeScript
Client
EventSource (browser) or eventsource (Node)
Language
Python
Client
sseclient-py
Language
Rust
Client
reqwest-eventsource

Future: 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

YieldFabric docs(317)