v3.4 — Java & Kotlin GA, Rust beta

SDKs without
the suffering.

One OpenAPI spec, eight idiomatic SDKs — TypeScript, Python, Go, Java, Kotlin, Ruby, C# and PHP — perfectly typed, automatically released, shipped the same day your API does.

4.8B SDK installs / month
8 languages, GA
SOC 2 Type II
create_response.py  ·  openai-sdk@4.91.0
 type-checked
1from openai import OpenAI
2
3client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
4
5response = client.responses.create(
6 model="gpt-4o-mini",
7 input="Summarize this PR in one sentence.",
8 max_output_tokens=120,
9 temperature=0.2,
10 metadata={"request_id": req_id},
11)
12
13# typed: ResponsesResponse — autocompleted everywhere
14print(response.output_text)
1import OpenAI from "openai";
2
3const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
4
5const response = await client.responses.create({
6 model: "gpt-4o-mini",
7 input: "Summarize this PR in one sentence.",
8 max_output_tokens: 120,
9 temperature: 0.2,
10 metadata: { request_id: reqId },
11});
12
13// typed: Response — discriminated unions, narrowed by status
14console.log(response.output_text);
1package main
2
3import (
4 "context"
5 "github.com/openai/openai-go"
6 "github.com/openai/openai-go/option"
7)
8
9client := openai.NewClient(option.WithAPIKey(key))
10resp, err := client.Responses.Create(ctx, openai.ResponseNewParams{
11 Model: openai.F("gpt-4o-mini"),
12 Input: openai.F("Summarize this PR in one sentence."),
13 MaxOutputTokens: openai.F(int64(120)),
14 Temperature: openai.F(0.2),
15})
1import com.openai.client.OpenAIClient;
2import com.openai.client.okhttp.OpenAIOkHttpClient;
3import com.openai.models.responses.ResponseCreateParams;
4
5OpenAIClient client = OpenAIOkHttpClient.fromEnv();
6
7ResponseCreateParams params = ResponseCreateParams.builder()
8 .model("gpt-4o-mini")
9 .input("Summarize this PR in one sentence.")
10 .maxOutputTokens(120)
11 .temperature(0.2)
12 .build();
13
14var response = client.responses().create(params);
1import com.openai.client.OpenAIClient
2import com.openai.client.okhttp.OpenAIOkHttpClient
3import com.openai.models.responses.ResponseCreateParams
4
5val client: OpenAIClient = OpenAIOkHttpClient.fromEnv()
6
7val response = client.responses().create(
8 ResponseCreateParams.builder()
9 .model("gpt-4o-mini")
10 .input("Summarize this PR in one sentence.")
11 .maxOutputTokens(120)
12 .temperature(0.2)
13 .build()
14)
generated 14 sec ago · passing
Type hint
max_output_tokens?: number
Min: 16 · Max: 16,384
Powering the SDKs developers actually npm install
4.8B monthly installs
412 production APIs
99.99% generation SLA
OOpenAI AAnthropic CCloudflare GGoogle MModern Treasury IIncrease CCourier BBeeper TTurbopuffer DDodopayments LLangChain RResend OOpenAI AAnthropic CCloudflare GGoogle MModern Treasury IIncrease CCourier BBeeper TTurbopuffer DDodopayments LLangChain RResend
[01] ONE SPEC — EIGHT SDKs

One OpenAPI spec.
Eight idiomatic SDKs.

Push a change to your openapi.yaml. Stainless regenerates every SDK in under 90 seconds, opens a PR per language, runs the type-checker, and waits for your /approve. No hand-edits, no drift, no 2 a.m. release engineering.

87s
Median full regen, 8 langs
0
Hand-written wrapper files
100%
Type coverage, every release
openapi.yaml · main
12paths:
13  /v1/responses:
14    post:
15      summary: Create response
16      requestBody:
17        $ref: '#/cmp/Req'
18      responses:
19        '200':
20          $ref: '#/cmp/Res'
Pythonopenai-python
TypeScriptopenai-node
Goopenai-go
Javaopenai-java
Kotlinopenai-kotlin
Rubyopenai-ruby
C#openai-dotnet
PHPopenai-php
[02] CORRECTNESS BY DEFAULT

Three things every SDK should already do.

Stainless ships the parts every SDK needs and most teams quietly cut. You inherit them on day one — in every language, identically.

End-to-end type safety, narrowed by status code

Discriminated unions, generics, sealed classes — whatever the language idiom is, your IDE knows the shape of response.output the moment you handle the 200.

if (response.status === 200) { response.data.output_text // string } else if (response.status === 429) { response.error.retry_after // number }

Idiomatic per language, never lowest-common-denominator

Builders in Java. Async iterators in TypeScript. context.Context first-arg in Go. Pythonic kwargs. Kotlin DSLs. Each SDK reads like it was hand-written by the team that wrote the language.

Python — pep8 TS — strict mode Go — golint clean Java — JDK 17+

Versioning, releases & changelogs — on rails

SemVer detection on every diff. CHANGELOG drafted from your spec changes. PRs to npm, PyPI, Maven Central, pkg.go.dev, NuGet and RubyGems — all signed, all reproducible.

4.91.0minorAdded responses.tools[]
4.90.2patchRetry on 503 with jitter
4.90.1patchPagination: handle empty cursor
4.90.0majorDrop Node 18 · Migration guide
[03] EVERYTHING ELSE, ALSO GENERATED

Docs, tests, MCP — from the same spec.

The OpenAPI document is the single source of truth. Stainless reads it once and emits everything downstream — reference docs, integration guides, golden tests, even an MCP server that lets Cursor and Claude Code call your API safely.

DOCS PLATFORM

Reference + handwritten guides, perfectly in sync

Stainless owns the API reference. You author the prose. Both ship from the same git repo with version branches, Algolia search, custom domain and AI chat baked in.

Quickstart
Authentication
Streaming
Webhooks
Errors
REFERENCE
/responses
/embeddings
/files
curl https://api.example.com/v1/responses \ -H "Authorization: Bearer $KEY" \ -d '{"input":"hello"}'
MCP SERVER

One-click MCP for Cursor & Claude

Token-efficient tool definitions, scoped auth, paginated results. Your customers' agents never burn context discovering your API.

GOLDEN TESTS

180+ tests per SDK, generated

Recorded against a mock server, replayed on every PR. Catches drift before npm sees it.

CHANGELOG & SEMVER

Breaking-change detection, automatic

A removed enum value or a tightened required field bumps you to a major release — with the migration guide drafted.

PR #4,221majorremoved model_v1
COVERAGE

96.4% endpoint coverage, audited weekly

Every endpoint in your spec has a generated test, a doc page, and an SDK method — or you get a PR explaining why.

endpoints — week 1996.4% · 412 / 427
[04] SEE ONE BUILD

From spec to shipped, in one view.

Pick any file in the generated SDK on the right. The OpenAPI fragment that produced it stays pinned on the left. Audit the whole pipeline without leaving a single screen.

openai / build #4,219 / main
spec → SDK tests · 1,284 / 1,284 87.4s
openapi.yaml
L 144 — 187 · + added
144 /v1/responses:
145 post:
146 operationId: createResponse
147 requestBody:
148 required: true
149 content:
150 application/json:
151 schema:
152 $ref: '#/components/schemas/CreateResponseReq'
153 responses:
154 '200':
155 description: Response object
156 content:
157 application/json:
158 schema:
159 $ref: '#/components/schemas/Response'
160 '429':
161 $ref: '#/components/responses/RateLimited'
162
163 # 8 SDKs regenerated · 0 hand-edits required
generated · openai-sdk monorepo
5 of 8 langs shown
openai-python
responses.py
openai-node
responses.ts
openai-go
responses.go
openai-java
ResponseService.java
openai-ruby
responses.rb
1# File generated from our OpenAPI spec by Stainless. Do not edit.
2from __future__ import annotations
3
4class Responses(SyncAPIResource):
5 def create(
6 self,
7 *,
8 model: str,
9 input: str | List[InputItem],
10 max_output_tokens: int | NotGiven = NOT_GIVEN,
11 temperature: float | NotGiven = NOT_GIVEN,
12 metadata: Dict[str, str] | NotGiven = NOT_GIVEN,
13 extra_headers: Headers | None = None,
14 timeout: float | httpx.Timeout | None = NOT_GIVEN,
15 ) -> Response:
16 """Create a model response. Typed, retried, paginated."""
17 return self._post(
18 "/v1/responses",
19 body=maybe_transform({...}, CreateResponseReq),
20 cast_to=Response,
21 )
1// File generated from our OpenAPI spec by Stainless. Do not edit.
2import { APIResource } from "../resource";
3
4export class Responses extends APIResource {
5 async create(
6 body: ResponseCreateParams,
7 options?: RequestOptions,
8 ): Promise<Response> {
9 return this._client.post("/v1/responses", { body, ...options });
10 }
11}
12
13export interface ResponseCreateParams {
14 model: string;
15 input: string | InputItem[];
16 max_output_tokens?: number;
17 temperature?: number;
18 metadata?: Record<string, string>;
19}
1// Code generated by Stainless — DO NOT EDIT.
2package openai
3
4type ResponseService struct { Options []option.RequestOption }
5
6func (r *ResponseService) Create(
7 ctx context.Context,
8 body ResponseNewParams,
9 opts ...option.RequestOption,
10) (res *Response, err error) {
11 err = requestconfig.ExecuteNewRequest(
12 ctx, http.MethodPost, "v1/responses", body, &res, opts...,
13 )
14 return
15}
1// Generated by Stainless. Do not edit.
2package com.openai.services.blocking;
3
4public interface ResponseService {
5 Response create(ResponseCreateParams params);
6 Response create(ResponseCreateParams params, RequestOptions opts);
7}
8
9public final class ResponseCreateParams {
10 public static Builder builder() { return new Builder(); }
11 public static class Builder {
12 public Builder model(String model) { ... }
13 public Builder input(String input) { ... }
14 public Builder maxOutputTokens(long n) { ... }
15 public ResponseCreateParams build() { ... }
16 }
17}
1# File generated from our OpenAPI spec by Stainless.
2module OpenAI
3 module Resources
4 class Responses
5 def create(model:, input:, max_output_tokens: nil, temperature: nil, **opts)
6 @client.request(
7 method: :post,
8 path: "/v1/responses",
9 body: { model:, input:, max_output_tokens:, temperature: },
10 model: OpenAI::Models::Response,
11 )
12 end
13 end
14 end
15end
[05] VS THE ALTERNATIVES

Why teams move off OpenAPI Generator and stay.

The honest matrix — where the open-source generator wins, where hand-written wrappers win, and where Stainless earns the line item.

Stainless/ managed swagger / openapi-generator/ open source Hand-written SDK/ in-house
Idiomatic per language ● Yes — per-lang specialists ◐ Templated — reads generated ● Yes — if you staff for it
Type-narrowed by status code ● Yes — discriminated unions ○ No — one return type ◐ If you wrote it that way
Streaming, retries, pagination ● Built-in, all 8 langs ○ Manual per language ◐ Hand-rolled, drifts over time
SemVer + auto changelog ● Drafted from spec diff ○ You write it ○ You write it
Publish to npm/PyPI/Maven/… ● Signed releases, all registries ◐ CI you maintain ◐ CI you maintain
Docs co-generated & in sync ● Reference + handwritten, one repo ○ Separate tool ○ Separate tool
MCP server for agent use ● One-click, scoped auth ○ Not supported ○ Build it yourself
Time to first published SDK ● Day 1, 8 languages ◐ Week 1, 1 language well ○ Quarter 1, 1 language
Total cost of ownership / yr ~$6K–$60K, 1 generator ~$280K, 1.5 SDK engineers ~$1.4M, 5+ SDK engineers
[06] PRICING

Priced per generator, not per seat.

Start free, upgrade when you ship to production. Volume discounts kick in at three generators — the second SDK in the same org is always 30% off.

Free
$0/ month
Everything you need to evaluate Stainless on a private SDK.
  • Up to 5 generators
  • 25 endpoints · 100 builds / month
  • All 8 languages, GA
  • Community Discord
  • Custom auth & OAuth
  • Mock & live test server
Enterprise
Talk/ to sales
For platforms whose SDKs are someone else's critical path.
  • Unlimited endpoints & custom code
  • SSO, SCIM, audit logs
  • Dedicated solution architect
  • SLAs, SDK version pinning
  • White-glove migration from in-house
  • SOC 2 Type II, HIPAA-ready
[07] FROM THE TEAMS USING IT

What platform engineers say after they migrate.

Six interviews with current customers, lightly edited. The full quotes — and the engineers' contact details for reference checks — are available on request.

"We were maintaining four SDKs by hand and falling behind on three of them. After Stainless, the team that used to ship one client a quarter ships eight on the day the spec lands. The Java SDK is the one our largest customer integrates against — we hadn't touched Java in two years."
MN
Maya Nakamura
Staff Engineer, Platform · Modern Treasury
"Our SDKs are how developers feel the API. Stainless raised that bar in a single quarter — the Python SDK alone went from 6/10 community sentiment on Twitter to a 4.9 on PyPI. We no longer have a person whose job title is 'SDK release engineering'."
DH
Daniel Huang
Head of DevRel · Cloudflare Workers AI
"I was the skeptic. I'd written three SDK generators in my career and none of them survived contact with reality. The thing that won me over was reading the diff: every file Stainless emitted looked like code I would have written if I'd had two more weeks per SDK."
PR
Priya Rao
Director of API Platform · Increase
"The day we shipped TypeScript and Python in the same release, support tickets dropped 38% in a fortnight. Most of them were 'how do I paginate' — which we now answer with autocomplete instead of a Discord thread."
TS
Thomas Sjölander
CTO · Turbopuffer
"Stainless is the cheapest senior SDK engineer we'll ever hire — and it's eight of them, working in eight languages we don't have to interview for."
EK
Elena Kovács
VP Engineering · Courier
"What sold our infra-sec team was the audit log on every release: who triggered the regen, what spec hash, what files changed, signed by Stainless's CI. We replaced four bespoke release pipelines with one Slack approval step."
JO
Jordan Okafor
Principal Engineer · Beeper
[08] QUESTIONS WE GET ON EVERY FIRST CALL

Twelve honest answers.

If your question isn't here, email hi@stainless.com — a real engineer replies, in our experience under four hours during US/EU business days.

3 engineers on call — Avg reply 3h 42m
No. Stainless ships a linter and an interactive spec doctor that flags ambiguous discriminators, inconsistent naming, missing examples, and the seven other things that make most generators choke. We'll send a cleanup PR back to your spec repo on day one.
Yes — that's the point. Each SDK has reserved extras/ directories that survive every regen. On Pro you get up to 10,000 lines; on Enterprise the limit is removed. Custom helpers, ergonomic shortcuts, framework adapters — ship them and forget about merge conflicts.
Every spec change is diffed against the previous build. Removed enums, tightened required fields, type-narrowing on responses — all flagged as MAJOR with a generated migration guide before the PR is opened. You can block the release with a single label.
npm, PyPI, Maven Central, Sonatype, pkg.go.dev, NuGet, RubyGems, Packagist, Terraform Registry. Releases are signed with our CI key; you can BYO signing key on Enterprise.
Rust is in private beta with three design partners (one of them OpenAI). Swift is in active development, ETA Q4 2026. Both will reach GA before we add the next language — we don't ship a generator until the language idiom is right.
Yes — in every language, identically. SSE and chunked streaming with proper backpressure, exponential backoff with jitter on 5xx and 429, automatic cursor and offset pagination with iterator helpers. You configure them once in the spec; we wire them into all eight SDKs.
We ship the API reference for free if you use Stainless for SDKs — no separate seat. Custom domain, MDX/Markdoc, AI chat trained on your spec, Algolia DocSearch, branch previews, and a CLI for local writing. The reference and the SDKs share a build, so they cannot drift.
It exposes your API as a Model Context Protocol server with token-efficient tool definitions: descriptions trimmed to what an agent needs, scoped auth via the same OAuth flow your SDK uses, paginated results with cursors. Cursor, Claude Code and Codex pick it up natively.
Yes. We support OAuth 2.0 (all grant types), API keys, JWTs, AWS SigV4, mTLS, and HMAC-signed requests out of the box, plus a custom auth hook for anything bespoke. The auth code is shared across SDKs, so a fix in one is a fix in all.
You do, perpetually. The generated SDKs live in your GitHub org under your license. If you stop paying, you keep the last build forever — we just stop regenerating new ones.
Median time-to-first-merged-SDK across our last 50 customers: 6 days for a team that already has a clean spec, 14 days otherwise. Enterprise comes with a solutions architect who runs the spec audit with your team in the first week.
If your API surface area is unusual — gRPC-only, GraphQL-only, or SOAP — Stainless isn't the right tool yet. We're an OpenAPI-first company. Tell us anyway; we keep a list and call when we're close.
[09]   SHIP TODAY

Your spec, eight SDKs,
by Friday.

Free up to five generators. No card. No sales call. The same build pipeline that powers OpenAI, Anthropic and Cloudflare — pointed at your openapi.yaml.

SOC 2 Type II GDPR 99.99% generation SLA 14-day Pro trial