Skip to content
  • Auto
  • Light
  • Dark
FeedbackDashboard
View as Markdown
Copy Markdown

Open in Claude
Open in ChatGPT

OpenAPI support

Stainless supports these primitives from the OpenAPI specification:

  • string
  • null
  • boolean
  • integer
  • number
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: float
Go
type Data struct {
String string
Nulls interface{}
Booleans bool
Integers int64
Numbers float64
}

Stainless supports multiple variations of object types.

# MapTypedValues
type: object
properties:
foo:
type: string
description: A foo property
bar:
type: boolean
required: [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"`
}

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()
}

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: kind

By 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.

# ObjectIntersection
allOf:
- $ref: '#/components/schemas/FooObject'
- type: object
properties:
baz:
type: string
- type: object
properties:
haz:
type: boolean
TypeScript
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"`
}

Stainless supports generating rich, language specific types for date and datetime schemas.

# DateObj
type: string
format: date
# DateTimeObj
type: string
format: date-time
TypeScript
// Not fully supported yet
export type DateObj = string;
export type DateTimeObj = string;
Python
import datetime
DateObj = datetime.date
DateTimeObj = datetime.datetime
Go
import "time"
type Data struct {
DateObj param.Field[time.Time] `format:"date"`
DateTimeObj param.Field[time.Time] `format:"date-time"`
}

Stainless supports OpenAPI’s additionalProperties specification which is equivalent to TypeScript’s Record type or Python’s dict type.

# MapTypedValues
type: object
additionalProperties:
type: integer
# MapUntypedValues
type: object
additionalProperties: true
TypeScript
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{}
}

Stainless does not support propertyNames, which is used to define the schema of the map key.

type: object
propertyNames:
type: string
enum: ["name", "email"]

Enums define a set of number and string literals that could be specified withing a field.

# FooModel
type: string
enum: [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'
)

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:

# FooModel
oneOf:
- const: 'bar'
description: 'A bar variant'
- const: 'baz'
description: 'A baz variant'
- const: 'bam'
description: 'A bam variant'

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: true
TypeScript
export type EmptySchema = {
foo: unknown;
};
Python
class EmptySchema(BaseModel):
foo: object
Go
type EmptySchema struct {
Foo interface{} `json:'foo'`
}

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.