opensdk.yaml is a machine-readable companion to your OpenAPI spec.
Declare how SDKs should be generated — naming conventions, retry logic,
pagination, reconciliation, packaging — once, for every language you support.
Every API provider that ships official SDKs must separately configure each generator
through a mix of CLI flags, config files, and template overrides. The result is
inconsistent: the Python SDK uses camelCase while Go uses snake_case
on the same resource. The TypeScript client silently drops retry logic the Java client
includes. The Terraform provider has reconciliation semantics no other language shares.
Consumers fare no better. A developer writing an integration must read provider documentation to discover that the "official" Go SDK requires 17 specific flags, or was generated with a private fork of a template set from three years ago.
opensdk.yaml alongside your
openapi.yaml — every compliant generator produces exactly the SDK you intended.
Naming conventions (camelCase, snake_case, PascalCase), enum representations, optional field styles, date types — per language.
Declare retry behavior with max attempts, backoff strategy (exponential, linear, fixed), and which HTTP status codes trigger a retry.
Cursor, offset, page-number, or link-header strategies. Opt into transparent iterator helpers that hide pagination from the caller entirely.
Terraform, Kubernetes, or Pulumi-style reconcile loops and drift detection for infrastructure SDKs. Declare immutable and server-managed fields.
Bearer, API key, Basic, OAuth2 (client credentials, authorization code, device code), and OIDC. Generators emit complete auth wrappers.
Package names, module paths, registry targets (npm, pypi, crates.io, pkg.go.dev, and more) — per language.
Validation gates that halt generation on unnamed operations, missing tags, or inline schemas. Breaking change policies. Versioning strategies.
Per-operation renames, ignores, forced deprecations, and custom implementations that replace generated code for specific endpoints.
SSE and chunked transfer helpers, webhook payload types, and HMAC signature verification — declared in one place, generated everywhere.
opensdk: "1.0.0"
openapi:
$ref: "./openapi.yaml"
sdk:
name: "acme-api"
version: "2.1.0"
license: "Apache-2.0"
languages:
- language: go
package:
name: "github.com/acme/acme-go"
style:
naming: snake_case
modelNaming: PascalCase
optionalStyle: pointer
features:
auth: bearer
retries:
enabled: true
maxAttempts: 3
backoff: exponential
reconciliation: terraform
context: true
- language: typescript
package:
name: "@acme/api"
registry: npm
style:
naming: camelCase
enumStyle: string-union
features:
auth: bearer
pagination:
strategy: cursor
iteratorHelper: true
streaming: true
webhooks: true
codegenRules:
validation:
- rule: no-unnamed-operations
severity: error
- rule: required-tags
severity: error
breakingChangePolicy: major-version-bump # validate before generating
$ opensdk validate ./opensdk.yaml
✓ Schema valid
✓ no-unnamed-operations passed
✓ required-tags passed
# generate Go SDK
$ opensdk generate --lang go \
--out ./sdk/go
✓ Generated 24 files
✓ Reconcile() helpers emitted
✓ context.Context threaded
# generate TypeScript SDK
$ opensdk generate --lang typescript \
--out ./sdk/ts
✓ Generated 18 files
✓ asyncIterator pagination
✓ Webhook HMAC verifier
✓ SSE streaming helpers
# publish
$ opensdk publish --lang go
✓ Published github.com/acme/acme-go@v2.1.0
$ opensdk publish --lang typescript
✓ Published @acme/api@2.1.0 → npm