--- title: Stainless OpenAPI extensions | Stainless description: 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](/docs/openapi/transforms/index.md). Some extensions have equivalent options in the [Stainless config file](/docs/sdks/configure/index.md), and the two approaches can be combined. For extensions that do have a config equivalent, most teams use the config file. Extensions are useful when you prefer to co-locate SDK hints with the relevant operation or schema in your spec. Some extensions are the only way to configure their behavior and have no config file equivalent. ## Operation extensions These extensions are placed on OpenAPI [Operation Objects](https://spec.openapis.org/oas/v3.0.3#operation-object). ### `x-stainless-method` Controls which [resource](/docs/sdks/configure#resources/index.md) and [method](/docs/sdks/configure#methods/index.md) 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` #### String shorthand 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 ``` #### Object form 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](/docs/reference/config#method/index.md) for available options. ### `x-stainless-snippets` 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(); ``` ### `x-stainless-deprecation-message` 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. ``` This extension also works on [Schema Objects](#x-stainless-deprecation-message-1). ### `x-stainless-examples` 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"}] ``` ## Schema extensions These extensions are placed on OpenAPI [Schema Objects](https://spec.openapis.org/oas/v3.0.3#schema-object) (typically under `#/components/schemas`). ### `x-stainless-model` Controls which [resource](/docs/sdks/configure#resources/index.md) and [model](/docs/sdks/configure#models/index.md) 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](/docs/sdks/configure#models/index.md). **Type:** `string | object` #### String shorthand 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 ``` #### Object form 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](/docs/reference/config#model/index.md) for available options. ### `x-stainless-skip` 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 ``` ### `x-stainless-model-skip` 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 ``` ### `x-stainless-model-only` Restricts a named model to only be generated in the specified languages. **Type:** `string[]` ``` components: schemas: TypeScriptOnlyHelper: x-stainless-model-only: [node] type: object ``` ### `x-stainless-override-schema` 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 ``` ### `x-stainless-param` 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 ``` ### `x-stainless-empty-object` 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 ``` This extension also works on [Parameter Objects](#parameter-extensions). ### `x-stainless-any` 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](/docs/openapi/requirements#unknown-and-any/index.md). ### `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 ``` ## Naming and enums These extensions control how types, properties, and enum values are named in generated SDKs. ### `x-stainless-naming` 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>` ``` components: schemas: APIToken: x-stainless-naming: go: type_name: ApiToken python: type_name: api_token type: object ``` ### `x-stainless-variantName` 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 ``` ### `x-stainless-renameMap` 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` ``` components: schemas: HttpStatusCode: type: integer enum: [200, 404, 500] x-stainless-renameMap: Ok: 200 NotFound: 404 InternalServerError: 500 ``` ### `x-stainless-const` 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 ``` ### `x-stainless-nominal` 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 ``` This extension is currently only supported in Go. ### `x-stainless-enum-deprecations` 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." ``` ## Pagination ### `x-stainless-pagination-property` 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 value | Description | | --------------------------- | ------------------------------------------------------------- | | `items` | The response field containing the page’s data array | | `next_cursor_field` | The response field containing the next page cursor | | `next_cursor_param` | The request parameter that accepts a cursor string | | `next_cursor_id_param` | The request parameter that accepts a cursor item ID | | `previous_cursor_id_param` | The request parameter for backward pagination | | `cursor_item_id` | The response field containing the cursor item ID | | `cursor_url_field` | The response field containing the next page URL | | `offset_count_param` | The request parameter for offset-based pagination | | `offset_total_count_field` | The response field with the total item count | | `offset_count_start_field` | The response field with the starting offset for the next page | | `page_number_param` | The request parameter for page number pagination | | `current_page_number_field` | The response field with the current page number | | `total_page_count_field` | The response field with the total number of pages | For full configuration details and examples of each pagination type, see [Configure SDK pagination](/docs/sdks/configure/pagination/index.md). ## Request behavior These extensions control how request parameters are handled during SDK generation. ### `x-stainless-useDefault` 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 ``` This extension also works on [Parameter Objects](#parameter-extensions). ### `x-stainless-soft-required` 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 ``` ## Webhooks ## Language-specific extensions These extensions only affect SDK generation for a specific language. ### TypeScript #### `x-stainless-typescript-use-array-suffix` 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 ``` This extension exists for backward compatibility. New schemas should not use it. ## Terraform extensions These extensions configure behavior specific to Terraform provider generation. ### `x-stainless-terraform-configurability` 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"` | Value | Description | | ------------------- | ----------------------------------------------------------------------------- | | `required` | The user must provide this value | | `optional` | The user can optionally provide this value | | `computed` | The value is computed by the API and cannot be set | | `computed_optional` | The 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](/docs/terraform/index.md). ### `x-stainless-collection-type` 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 ``` ### `x-stainless-terraform-always-send` 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 ``` ## Media type extensions ### `x-stainless-only` Restricts a media type to only be used when generating SDKs for the specified languages. Place this on a [Media Type Object](https://spec.openapis.org/oas/v3.0.3#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 ``` ## Parameter extensions Several extensions listed above can also be placed directly on OpenAPI [Parameter Objects](https://spec.openapis.org/oas/v3.0.3#parameter-object), in addition to Schema Objects: | Extension | On schemas | On parameters | | --------------------------------------------------------- | ---------- | ------------- | | [`x-stainless-useDefault`](#x-stainless-usedefault) | Yes | Yes | | [`x-stainless-empty-object`](#x-stainless-empty-object) | Yes | Yes | | [`x-stainless-soft-required`](#x-stainless-soft-required) | No | Yes | | [`x-stainless-param`](#x-stainless-param) | Yes | Yes |