SDK Generator
Migrate off Stainless Read moreIdiomatic, type-safe client libraries generated from the OpenAPI document your team already maintains. Pick your targets, review real code in minutes, and publish from your own repositories through pull requests you control.
import WarpAPI from "warp-hr";
const client = new WarpAPI({
apiKey: process.env["API_KEY"], // defaults to the API_KEY env var
});
const assignments = await client.timeOff.listAssignments();
import os
from warp import Warp
client = Warp(
api_key=os.environ.get("WARP_API_KEY"),
)
time_off = client.time_off.list_assignments()
package main
import (
"context"
"os"
sdk "github.com/TeamWarp/warp-go-sdk"
"github.com/TeamWarp/warp-go-sdk/option"
)
func main() {
client := sdk.NewClient(
option.WithAPIKey(os.Getenv("WARP_API_KEY")),
)
timeOff, err := client.TimeOff.ListAssignments(context.Background(), sdk.TimeOffListAssignmentsParams{})
if err != nil {
panic(err)
}
_ = timeOff
}
Generate from the OpenAPI 3.0 or 3.1 document your team already maintains. Swagger 2.0 is upgraded on load.
Each target is written to the conventions of its language, not templated from one shared shape.
Edit generated files directly. Every rebuild carries your changes forward through a three-way merge.
API keys, Basic, Bearer, OAuth 2.0, and OIDC, wired from the security schemes in your description.
Versions, changelogs, and releases land as reviewable pull requests in your own repository.
Generate a full command-line client alongside your SDKs, with typed flags and structured output.
Server-sent events, newline-delimited JSON, WebSockets, and multipart file uploads.
Every SDK ships an Agent Skill and a generated reference, so agents call your API correctly.
Targets and registries
Every target publishes to the registry its ecosystem expects, using workflows generated into your repository.
Generally available
| Target | Package registry |
|---|---|
| TypeScript | npm |
| Python | PyPI |
| Go | Go modules |
| CLI | npm and Homebrew |
Experimental
| Target | Package registry |
|---|---|
| Java | Maven Central |
| Kotlin | Maven Central |
| Ruby | RubyGems |
| C# | NuGet |
| PHP | Packagist |
| Rust | crates.io |
| Swift | Swift Package Manager |
| Dart | pub.dev |
| C++ | No standard registry |
Generally available targets carry end-to-end tests that generate, build, and run against a live server on every change. Experimental targets generate working code, and Java, Kotlin, Ruby, and C# sit in the same test matrix, but the label is there for a reason: talk to us before you depend on one.
Generated, not templated
Template-based generators map each operation to a method mechanically. The result compiles, but nobody wants to write against it: the resource noun appears twice in every call, optional parameters arrive positionally, and the response is buried behind a transport object.
import { Configuration, TimeOffApi } from "./generated";
const config = new Configuration({
basePath: "https://api.warp.dev",
apiKey: process.env.WARP_API_KEY,
});
const api = new TimeOffApi(config);
const response = await api.timeOffListAssignmentsGet(
undefined, // limit
undefined, // cursor
undefined, // options
);
const assignments = response.data;
import WarpAPI from "warp-hr";
const client = new WarpAPI({
apiKey: process.env["API_KEY"], // defaults to the API_KEY env var
});
const assignments = await client.timeOff.listAssignments();
Two details do most of that work. The client is named after your API and exported as the default export, so the import reads like the product. And credentials come from a conventional environment variable, so the happy path does not require passing a secret at all.
The third is method naming. Scalar strips the redundant resource noun and normalizes the verb, so the same handful of methods appears on every resource:
operationId |
Template-based generator | Scalar |
|---|---|---|
listPets |
client.pets.listPets() |
client.pet.list() |
getPetById |
client.pets.getPetById() |
client.pet.retrieve() |
addPet |
client.pets.addPet() |
client.pet.create() |
Across a large API that consistency is the difference between guessing a method name and knowing it. For a fuller side-by-side against another generator, see Scalar vs Fern.
Everything a hand-written SDK does
Types
- Typed request and response models for every operation, generated from your schemas.
oneOf,anyOf, andallOflowered into real union types, with discriminator support.- Typed errors exposing status, headers, the parsed response body, and request metadata.
- Documented error statuses enumerated per operation, so handling failures is not guesswork.
- Zero runtime dependencies unless you enable a feature that needs one. The generated Warp package ships
"dependencies": {}.
Networking
- Auto-paginating iterators across ten pagination schemes: cursor, cursor id, cursor URL, offset, page number,
Linkheader, header token, body link, compound cursor, andhasMore. - Streaming responses over server-sent events and newline-delimited JSON, with event metadata preserved.
- WebSockets with separate Node and browser adapters.
- File uploads as multipart, URL-encoded, or raw binary.
- Multi-content-type operations get a content-type selector instead of a guess.
Reliability
- Retries on temporary failures, defaulting to two attempts and covering network errors, 408, 409, 429, and 5xx responses.
Retry-Afteris honored when the server sends it, with configurable backoff otherwise.- Timeouts default to 60 seconds and can be overridden per request.
- Idempotency keys per request, using the header your API expects.
- Raw response access so you can read the underlying response and parse it yourself.
- Custom HTTP client injection for your own transport, middleware, or instrumentation.
Authentication
- API keys in a header, query parameter, or cookie.
- HTTP Basic and Bearer, with Basic split into separate username and password options.
- OAuth 2.0 and OIDC schemes declared in your description.
- Environment variable defaults per credential, so the quickstart needs no secrets inline.
- Async credential providers for tokens you have to fetch or refresh yourself.
- Typed webhook events from
webhooksand operationcallbacks, with HMAC-SHA256 signature verification, multi-secret rotation, and timestamp tolerance.
Docs and agents
- An Agent Skill written to
SKILL.mdand.claude/skills/, so coding agents discover how to call your API. - A generated
api.mdlisting every method grouped by resource, with request and response types linked to source. - Code samples injected into your OpenAPI as
x-codeSamplesand rendered in your API reference. Examples you curated by hand are preserved. - A generated README with authentication, client option, and request option tables filled in from your description.
- An async counterpart in languages that have one, exposing the same resource tree.
Releases
- Version and changelog pull requests managed by release-please against the branch you nominate.
- Publishing workflows generated into your repository for eleven registries, with actions pinned by commit SHA.
- Trusted publishing where the registry supports it, so no long-lived tokens are needed.
- Conventional Commit messages describing what actually changed in the SDK surface, marked as breaking when they are.
- Smoke tests that call every operation against a mock server and report the result.
How it works
Start from your OpenAPI document
Put your API description in Registry, or import it while creating the SDK. OpenAPI 3.0 and 3.1 are supported, and Swagger 2.0 documents are upgraded on load.
Pick your targets
Read the code before committing to anything
Every target gets a preview repository, provisioned automatically. Browse the generated code, the api.md reference, and the README before you wire up a repository of your own.
Link your own repository
Connect the repository where the SDK should live. Scalar authors commits through a GitHub App installation, never a personal token. Every build pushes generated output to scalar-generated, merges it with your custom code on scalar-next, and keeps a release pull request open against the branch you nominate.

Publish from your repository
release-please versions the release pull request from your commit history and maintains the changelog. When you merge it, the workflows in your repository cut the tag and GitHub Release and publish the package. Your package names, registries, and release history stay yours. See publishing.
Let it follow your API
Point each SDK at an exact version of your API document or at a semver range such as ^1.2.0. When a matching document changes, Scalar mints a new SDK version and rebuilds, so one commit updates every target.
Your custom code survives regeneration
Generated SDKs rarely cover every need. You will want a convenience method, a tweaked type, a helper, or a better README, and no generator should make you choose between that and staying up to date.
Edit generated files as you would any other code. Every build performs a three-way merge between the previous generation, the new generation, and the current state of your repository, then opens a pull request combining the two. Untouched files update cleanly, your edits ride along, and files you added yourself are left alone.
For code you want held in place explicitly, mark a region:
// scalar-sdk-generator:custom-code retry-helper:start
export const withBackoff = async <T>(fn: () => Promise<T>) => {
// Anything in here is carried forward on every regeneration.
};
// scalar-sdk-generator:custom-code retry-helper:end
Conflicts happen only when a regenerated file changes the same lines you edited. When that happens, the build surfaces the conflict as a pull request you resolve on GitHub like any other merge conflict. The whole flow runs on managed branches you can inspect yourself: scalar-generated holds pristine output, scalar-next holds output merged with your commits, and scalar-merge-conflict carries anything that needs a human. Read more in custom code.
Built for coding agents
Agents write a growing share of the code that calls your API, and they are the consumers most likely to invent a method name that does not exist. Every generated SDK ships the context needed to prevent that.
- An Agent Skill at
SKILL.md, plus.claude/skills/<name>/SKILL.mdfor automatic discovery, covering installation, client construction, authentication, and how to look up a call signature. - A generated
api.mdlisting every operation with its request and response types, designed to drop straight into an agent's context. - An
openapi.augmented.jsoncarrying your description alongside generated code samples and installation metadata.
All three are on by default, and all three are readable right now in the generated Warp SDK.
Tested against SDKs that ship
An SDK generator is only worth what its output survives, so most of the engineering here is testing rather than templating.
A harness compares our output to client libraries companies actually publish, on public API shape and on live wire traffic.
Generated harnesses call every operation against a mock server and report which ones fail.
The parity harness is the part we would want to see as a buyer. It clones production SDKs at pinned commits, extracts the public surface from both, and fails on drift in operation coverage, wire shapes, unions, enums, pagination behavior, requiredness, or parameter location. Then it drives both clients through every shared operation against a recording mock and diffs the requests they send.
Coming from Stainless?
Stainless is winding down its hosted SDK generator. Scalar reads your existing stainless.yml directly, so your resources, method names, pagination schemes, and per-language package names carry across and the call sites your users have already written keep working.
Read the Stainless migration guide.
Plans
SDK generation is billed per target, at $100 per month or $1,000 per year.
| Free | Pro | Enterprise | |
|---|---|---|---|
| SDKs | 1 | 3 | Unlimited |
| Targets | 1 | Billed per target | Billed per target |
| Every target free during your trial | Included | Included | Included |
| SSO/SAML, RBAC, priority support, and dedicated Slack or Teams support | - | - | Included |
A target becomes billable when you save a version and queue its build. Drafts are never billed. See the full comparison for SDKs and the other Scalar products.
Questions
Which targets are production ready?
TypeScript, Python, Go, and the CLI target are generally available. The rest are marked experimental in the dashboard. Java, Kotlin, Ruby, and C# sit in the same continuous integration matrix as the generally available targets and are the closest behind them. PHP, Rust, Swift, Dart, and C++ generate working code, and we would rather talk to you first than have you discover a gap in production.
Do I own the generated code?
Yes. The SDK lives in your repository, under your package name, published to your registry accounts. Scalar opens pull requests against it and never cuts tags or releases on your behalf.
What happens to code I wrote by hand?
It is carried forward. Every build three-way merges the new generation with the current state of your repository, so your edits survive. Marked custom-code regions are preserved explicitly, and files you added yourself are never touched. Conflicts arrive as a pull request you resolve on GitHub.
Where can SDKs be published?
npm, PyPI, Go modules, Maven Central, RubyGems, NuGet, Packagist, crates.io, the Swift Package Manager, pub.dev, and Homebrew for CLI targets. Publishing runs from workflows generated into your repository, with actions pinned by commit SHA and trusted publishing where the registry supports it.
Which authentication schemes are supported?
API keys in a header, query parameter, or cookie; HTTP Basic; Bearer tokens; and OAuth 2.0 and OIDC schemes declared in your description. Each credential gets an environment variable default, and you can supply an async provider for tokens you fetch or refresh yourself.
Does my OpenAPI document need to be perfect?
No. Scalar generates a starting configuration from whatever you have, covering naming, pagination, and authentication. You then refine it in the configuration editor rather than by rewriting your description.
What keeps my SDKs in sync with the API?
Each SDK follows its API document by exact version or by a semver range you set. When a matching document changes, Scalar mints a new SDK version, rebuilds every target, and opens the pull requests. One commit to your API updates all of your clients.
Ready to generate your first SDK?
Follow the Getting Started guide to generate a target from the dashboard, or bring an existing configuration and we will do the migration with you.
