OpenAPI support
Schemas and types
Section titled “Schemas and types”Primitives
Section titled “Primitives”Stainless supports these primitives from the OpenAPI specification:
stringnullbooleanintegernumber
TypeScript
export interface Data { strings: string; nulls: null; booleans: boolean; integers: number; numbers: number;}Python
class Data(BaseModel): strings: str nulls: None booleans: bool integers: int numbers: floatGo
type Data struct { String string Nulls interface{} Booleans bool Integers int64 Numbers float64}object
Section titled “object”Stainless supports multiple variations of object types.
# MapTypedValuestype: objectproperties: foo: type: string description: A foo property bar: type: booleanrequired: [foo]TypeScript
interface FooObject { // A foo field foo: string: bar?: boolean;}Python
class FooObject(BaseModel): # A foo field foo: str bar: Optional[bool]Go
type FooObject struct { // A foo field Foo string `json:"foo,required"` Bar bool `json:"bar"`}oneOf and anyOf
Section titled “oneOf and anyOf”Stainless treats both oneOf and anyOf as equivalent to a TypeScript union.
oneOf: - type: object properties: foo: type: string required: [foo] - type: object properties: bar: type: boolean required: [bar]TypeScript
export interface FooObj { foo: string;}
export interface BarObj { bar: boolean;}
export type Schema = FooObj | BarObj;Python
class FooObj(BaseModel): foo: str
class BarObj(BaseModel): bar: bool
Schema = Union[FooObj, BarObj]Go
type FooObj struct { Foo string `json:"foo"`}func (*FooObj) implementsSchema() {}
type BarObj struct { Bar bool `json:"bar"`}func (*BarObj) implementsSchema() {}
type Schema interface { implementsSchema()}discriminator
Section titled “discriminator”A discriminator property for a union schema allows mapping a JSON object to one of the variants by looking up a
single property. This simplifies deserialization and makes mapping much faster. We recommend that all unions
which have multiple object variants specify this in the schema.
oneOf: - type: object properties: kind: const: 'foo_object' foo: type: string required: [foo] - type: object properties: kind: const: 'bar_object' bar: type: boolean required: [bar] discriminator: propertyName: kindBy default, Stainless handles allOf by flattening the entries into one schema and treating it like an object.
However, if one of the entries is a model, then Stainless uses the model entry as a part of composition.
# ObjectIntersectionallOf: - $ref: '#/components/schemas/FooObject' - type: object properties: baz: type: string - type: object properties: haz: type: booleanTypeScript
export interface ObjectIntersection extends FooObject { baz?: string; haz?: boolean;}Python
class ObjectIntersection(BaseModel, FooObject): # A foo baz: Optional[str] has: Optional[bool]Go
type ObjectIntersection struct { FooObject Baz string `json:"baz"` Has bool `json:"has"`}date and date-time
Section titled “date and date-time”Stainless supports generating rich, language specific types for date and datetime schemas.
# DateObjtype: stringformat: date
# DateTimeObjtype: stringformat: date-timeTypeScript
// Not fully supported yetexport type DateObj = string;export type DateTimeObj = string;Python
import datetime
DateObj = datetime.dateDateTimeObj = datetime.datetimeGo
import "time"
type Data struct { DateObj param.Field[time.Time] `format:"date"` DateTimeObj param.Field[time.Time] `format:"date-time"`}additionalProperties
Section titled “additionalProperties”Stainless supports OpenAPI’s additionalProperties specification which is equivalent to TypeScript’s Record type or Python’s dict type.
# MapTypedValuestype: objectadditionalProperties: type: integer
# MapUntypedValuestype: objectadditionalProperties: trueTypeScript
export type MapTypedValues = Record<string, number>;export type MapUntypedValues = Record<string, unknown>;Python
MapTypedValues = Dict[str, int]MapUntypedValues = Dict[str, object]Go
type Data struct { MapTypedValues map[string]int64 MapUntypedValues map[string]interface{}}propertyNames
Section titled “propertyNames”Stainless does not support propertyNames, which is used to define the schema of the map key.
type: objectpropertyNames: type: string enum: ["name", "email"]enum and const
Section titled “enum and const”Enums define a set of number and string literals that could be specified withing a field.
# FooModeltype: stringenum: [bar, baz, bam]TypeScript
export type FooModel = 'bar' | 'baz' | 'bam'Python
FooModel = Literal['bar' | 'baz' | 'bam']Go
type FooModel string
const ( FooModelBar FooModel = 'bar' FooModelBaz = 'baz' FooModelBam = 'bam')x-enum-descriptions
Section titled “x-enum-descriptions”Stainless optionally supports providing enum member descriptions, which either get rendered in the member variables or the main enum type, depending on the language.
Descriptions can be provided with either the
x-enum-descriptions
extension or with a oneOf:
# FooModeloneOf: - const: 'bar' description: 'A bar variant' - const: 'baz' description: 'A baz variant' - const: 'bam' description: 'A bam variant'Unknown and Any
Section titled “Unknown and Any”Stainless supports specifying types that are unknown and any, and accepts any valid JSON value. The JSON
Schema way of specifying this behavior is to specify an ‘empty’ schema, but this often happens by accident.
Unless you add an x-stainless-any, Stainless adds a diagnostic note to your OpenAPI schema.
# EmptySchema (the OpenAPI default)type: 'object'properties: foo: x-stainless-any: trueTypeScript
export type EmptySchema = { foo: unknown;};Python
class EmptySchema(BaseModel): foo: objectGo
type EmptySchema struct { Foo interface{} `json:'foo'`}Parameter behavior
Section titled “Parameter behavior”default
Section titled “default”Stainless does not include default values from the OpenAPI spec in generated SDK methods. Parameters with defaults are treated the same as optional parameters without defaults. Stainless treats the default property as the server-defined default. If your server applies this default when the parameter is omitted, there’s no need to send it from the client. Not sending defaults from the client gives you more control over the value and allows you to change it without requiring SDK users to upgrade. Supporting defaults at arbitrary locations across all SDK languages would also require significant implementation tradeoffs.
For header parameters that need a default value sent with every request, configure them in your Stainless config using client_settings.default_headers:
client_settings: default_headers: X-Feature-Flag: 'enabled' X-API-Version: '2025-01-01'This will ensure these headers are sent automatically with every request made by the SDK. For query parameters or request body parameters, there is currently no equivalent configuration option in Stainless. These should be handled by your server applying the default when the parameter is omitted, or can be implemented via custom code.
Similarly, default values in response schemas are ignored by Stainless. Response defaults are expected to be applied server-side.