Skip to content
FeedbackDashboard
Your OpenAPI spec

Stainless OpenAPI extensions

Complete reference for x-stainless-* vendor extensions that configure SDK generation directly in your OpenAPI spec.

Stainless supports vendor extensions (fields prefixed with x-stainless-) that you add directly to your OpenAPI spec to configure how the SDK generator interprets your API. Extensions let you co-locate SDK hints with the relevant operation or schema instead of managing them in a separate config file.

You can also apply extensions without modifying your source spec by using OpenAPI transforms.

These extensions are placed on OpenAPI Operation Objects.

Controls which resource and method name Stainless uses when generating the SDK. Without this annotation, Stainless autogenerates a resource and method name, which you can also configure in the Stainless config file.

Type: string | object

The simplest form is a dotted string that identifies the resource path and method name:

paths:
/accounts:
get:
summary: List all accounts
x-stainless-method: accounts.list
responses:
'200':
description: A list of accounts

This is equivalent to the following Stainless config entry:

resources:
accounts:
methods:
list: get /accounts

For nested resources, use additional dots to represent the hierarchy:

paths:
/accounts/{account_id}/members:
get:
summary: List account members
x-stainless-method: accounts.members.list

For methods that belong directly on the client (not nested under a resource), use the special $client prefix:

paths:
/me:
get:
summary: Get current user
x-stainless-method: $client.me

You can use an object with a path property to supply additional method configuration alongside the resource path:

paths:
/v1/accounts:
get:
summary: List all accounts
x-stainless-method:
path: accounts.list
deprecated: Use /v2/accounts instead

The object accepts the same configuration options as methods in the Stainless config file. See the config reference for available options.

Provides hand-written code snippets for generated API documentation, overriding the auto-generated examples.

Type: object with language keys (for example, python, typescript, go, java, kotlin)

paths:
/accounts:
get:
x-stainless-snippets:
python: |
accounts = client.accounts.list()
node: |
const accounts = await client.accounts.list();

Provides a human-readable deprecation message for operations that have deprecated: true. This message appears in the generated SDK documentation and language-specific deprecation annotations (for example, @Deprecated in Java).

Type: string

paths:
/v1/accounts:
get:
deprecated: true
x-stainless-deprecation-message: Use /v2/accounts instead.

Provides custom code sample examples for an operation. These appear in generated API documentation.

Type: object | array

paths:
/accounts:
get:
x-stainless-examples:
title: List active accounts
request:
python: |
client.accounts.list(status="active")
node: |
await client.accounts.list({ status: 'active' });
response: |
[{"id": "acc_123", "name": "Acme Corp", "status": "active"}]

These extensions are placed on OpenAPI Schema Objects (typically under #/components/schemas).

Controls which resource and model name Stainless uses for a schema. Without this annotation, a schema that is not explicitly configured as a model is inlined (duplicated) everywhere it is referenced. You can also configure models in the Stainless config file.

Type: string | object

The simplest form is a dotted string that identifies the resource path and model name:

components:
schemas:
Account:
x-stainless-model: accounts.account
type: object
properties:
id:
type: string
name:
type: string

This is equivalent to the following Stainless config entry:

resources:
accounts:
models:
account: '#/components/schemas/Account'

For models that belong to a nested resource:

components:
schemas:
Member:
x-stainless-model: accounts.members.member
type: object

For models that are shared across resources, use the special $shared resource:

components:
schemas:
Address:
x-stainless-model: $shared.address
type: object

You can use an object with a path property to supply additional model configuration:

components:
schemas:
Account:
x-stainless-model:
path: accounts.account
type: object

The object accepts the same configuration options as models in the Stainless config file. See the config reference for available options.

Skips code generation for a schema entirely. Useful for schemas that exist in your spec for documentation but should not appear in generated SDKs.

Type: boolean | string[]

When set to true, the schema is skipped in every language. Pass an array of language names to skip only in specific languages.

components:
schemas:
InternalDetail:
x-stainless-skip: true
type: object
components:
schemas:
LegacyFormat:
x-stainless-skip: [go, java]
type: object

Prevents a schema from being generated as a named model, while still allowing it to be used inline. Unlike x-stainless-skip, the schema’s type information is still generated where it is referenced.

Type: boolean | string[]

components:
schemas:
InlineMetadata:
x-stainless-model-skip: true
type: object
properties:
key:
type: string

Restricts a named model to only be generated in the specified languages.

Type: string[]

components:
schemas:
TypeScriptOnlyHelper:
x-stainless-model-only: [node]
type: object

Entirely replaces the schema with the contents of this property during SDK generation. This is useful when you want Stainless to use a different schema than other tooling (for example, if your mock server does not support a certain schema construct).

Type: Schema Object

components:
schemas:
FlexibleInput:
type: string
x-stainless-override-schema:
oneOf:
- type: string
- type: object
properties:
value:
type: string

Controls whether a top-level request body schema is treated as a named parameter type and optionally renames it. When set to false, prevents the schema from generating a named params type. When set to a string, uses that string as the parameter type name. This extension only has an effect on schemas used as top-level request bodies.

Type: boolean | string

components:
schemas:
AccountCreateBody:
x-stainless-param: account_create_params
type: object
properties:
email:
type: string

Explicitly marks a schema as an empty object type. This resolves ambiguity when an object schema has no properties and additionalProperties: false, which could be interpreted as either an empty object or an unknown type.

Type: boolean

components:
schemas:
EmptyResponse:
type: object
properties: {}
additionalProperties: false
x-stainless-empty-object: true

Explicitly marks a schema as accepting any JSON value. The empty schema {} technically represents “any” in JSON Schema, but it often appears by accident. Adding x-stainless-any: true suppresses the diagnostic warning and signals intent.

Type: true

components:
schemas:
Metadata:
type: object
properties:
data:
x-stainless-any: true

For more details, see Unknown and any.

x-stainless-deprecation-message (on schemas)

Section titled “x-stainless-deprecation-message (on schemas)”

Provides a human-readable deprecation message for schemas that have deprecated: true. This message appears in the generated SDK documentation and language-specific deprecation annotations (for example, @Deprecated in Java).

Type: string

components:
schemas:
LegacyAccount:
deprecated: true
x-stainless-deprecation-message: Use the Account schema instead.
type: object

These extensions control how types, properties, and enum values are named in generated SDKs.

Overrides generated names on a per-language basis. The value is a map of language to a map of name categories (such as type_name) to their desired values. Each key in the inner map specifies how the name is used (for example, when the schema is used as a type name), not the schema name itself.

Type: Record<language, Record<string, string>>

components:
schemas:
APIToken:
x-stainless-naming:
go:
type_name: ApiToken
python:
type_name: api_token
type: object

Explicitly specifies the name of a schema variant that appears in a union (oneOf/anyOf). Useful when you need fine-grained control over generated type names without turning the schema into a standalone model.

Type: string

components:
schemas:
EventPayload:
oneOf:
- type: object
x-stainless-variantName: TextPayload
properties:
text:
type: string
- type: object
x-stainless-variantName: ImagePayload
properties:
url:
type: string

Renames string enum values in the generated SDK. The key is the new name and the value is the original enum value. This is particularly useful when your enum values are not valid identifiers in the target language (for example, numeric values).

Type: Record<string, string | number>

components:
schemas:
HttpStatusCode:
type: integer
enum: [200, 404, 500]
x-stainless-renameMap:
Ok: 200
NotFound: 404
InternalServerError: 500

Indicates that a single-value enum will never be expanded to include additional members. The SDK generator uses this signal to produce a more ergonomic interface. For example, in some SDKs, if this schema appears in a request parameter, the SDK sets the value automatically on behalf of the caller so they do not need to specify it manually.

Type: boolean

components:
schemas:
EventType:
type: string
enum: [account.created]
x-stainless-const: true

Controls whether an enum type is “nominal” (a distinct type) or an alias.

Type: boolean

When false (the default for most enums), the type is an alias and any compatible value can be assigned. When true, only predefined enum constants or explicit casts are accepted.

components:
schemas:
Currency:
type: string
enum: [USD, EUR, GBP]
x-stainless-nominal: true

In Go, this produces:

// nominal: false (alias, any string is assignable)
type Currency = string
// nominal: true (distinct type, must use constants or cast)
type Currency string

Marks individual enum members as deprecated. The value is an array parallel to the enum array. Each element is either false (not deprecated), true (deprecated without a message), or a string (deprecated with that message).

Type: (string | boolean)[]

components:
schemas:
Plan:
type: string
enum:
- free
- pro
- enterprise
- legacy
x-stainless-enum-deprecations:
- false
- false
- false
- "Use 'pro' instead."

Marks a request parameter or response field as having a specific role in a pagination scheme. This extension is placed on properties within the request and response sections of a pagination scheme definition.

Type: object with a purpose field

Purpose valueDescription
itemsThe response field containing the page’s data array
next_cursor_fieldThe response field containing the next page cursor
next_cursor_paramThe request parameter that accepts a cursor string
next_cursor_id_paramThe request parameter that accepts a cursor item ID
previous_cursor_id_paramThe request parameter for backward pagination
cursor_item_idThe response field containing the cursor item ID
cursor_url_fieldThe response field containing the next page URL
offset_count_paramThe request parameter for offset-based pagination
offset_total_count_fieldThe response field with the total item count
offset_count_start_fieldThe response field with the starting offset for the next page
page_number_paramThe request parameter for page number pagination
current_page_number_fieldThe response field with the current page number
total_page_count_fieldThe response field with the total number of pages

For full configuration details and examples of each pagination type, see Configure SDK pagination.

These extensions control how request parameters are handled during SDK generation.

Tells the SDK to use the schema’s default value when the parameter is not provided by the caller. Currently works for top-level parameters.

Type: boolean

paths:
/accounts:
get:
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
x-stainless-useDefault: true

Marks a parameter as soft-required: the SDK treats it as required in the method signature, but does not enforce it at the protocol level. This is only supported on Parameter Objects.

Type: boolean

paths:
/search:
get:
parameters:
- name: query
in: query
x-stainless-soft-required: true
schema:
type: string

These extensions only affect SDK generation for a specific language.

Appends Item to the generated type name when this schema is used inside an array. This exists for backward compatibility only.

Type: true

components:
schemas:
Account:
x-stainless-typescript-use-array-suffix: true
type: object

These extensions configure behavior specific to Terraform provider generation.

Explicitly sets the Terraform configurability of a schema property. This is useful for cases where an API returns normalized or default data if the field is not set by the user, but there is no static default in the spec to indicate this.

Type: "required" | "computed" | "optional" | "computed_optional"

ValueDescription
requiredThe user must provide this value
optionalThe user can optionally provide this value
computedThe value is computed by the API and cannot be set
computed_optionalThe user can optionally provide this value, but the API may compute a default
components:
schemas:
Zone:
type: object
properties:
status:
type: string
x-stainless-terraform-configurability: computed
name:
type: string
x-stainless-terraform-configurability: required

For more details on Terraform provider generation, see the Terraform documentation.

Specifies whether an array property should be a list or set attribute in the generated Terraform provider. Defaults to list.

Type: "list" | "set"

components:
schemas:
Zone:
type: object
properties:
tags:
type: array
items:
type: string
x-stainless-collection-type: set

When true, the property is always included in update requests even if the user has not explicitly configured it. If the value is not configured, the value from Terraform state is sent instead. Only applies to computed and computed-optional attributes.

Type: boolean

components:
schemas:
Zone:
type: object
properties:
settings:
type: object
x-stainless-terraform-always-send: true
x-stainless-terraform-configurability: computed_optional

Restricts a media type to only be used when generating SDKs for the specified languages. Place this on a Media Type Object.

Type: string[]

paths:
/upload:
post:
requestBody:
content:
multipart/form-data:
x-stainless-only:
- python
- node
schema:
type: object
properties:
file:
type: string
format: binary

Several extensions listed above can also be placed directly on OpenAPI Parameter Objects, in addition to Schema Objects:

ExtensionOn schemasOn parameters
x-stainless-useDefaultYesYes
x-stainless-empty-objectYesYes
x-stainless-soft-requiredNoYes
x-stainless-paramYesYes