Design schemas

⚠️
Preview — this feature is being built; the design below is the spec.

A schema does two jobs: it guarantees the shape your code receives, and it tells the model what you want. Write it for both readers.

Use enums for closed choices

{ "category": { "type": "string", "enum": ["billing", "technical", "account", "other"] } }

An enum is both validated and visible to the model. Always include an escape value such as other or unknown; without one the model is forced to pick a wrong answer when none fits.

Say “not present” explicitly

Prefer a required field that can be null over an optional field:

{ "order_number": { "type": ["string", "null"], "description": "The order number if the email gives one, else null." } }

Required-but-nullable means your code always finds the key, and the model is reminded to look for the value instead of quietly leaving it out.

Descriptions are instructions

Field descriptions are read by the model. Put format rules there, close to where they apply:

{ "amount": { "type": "string", "description": "Decimal with two places and no currency symbol, e.g. 49.00" } }

Order fields for reasoning

The model writes fields in schema order. When one field depends on judgment, put a short reason field before the verdict so the verdict is written after the reasoning:

{ "properties": { "reason": { "type": "string" }, "verdict": { "enum": ["approve", "reject"] } }, "required": ["reason", "verdict"] }

Keep arrays bounded

Use maxItems on arrays the model fills. An unbounded list of extracted entities on a long document can run into max_tokens and be cut off mid-object.

What to avoid

PatternProblemInstead
Deep anyOf / oneOf treesSlower validation, more retriesA type discriminator field plus a flat object
Free-form object with no propertiesNothing is constrainedName the keys you expect
Very long enums (hundreds of values)Costs tokens on every call; error-proneA string field plus your own lookup
pattern regexes for datesNot supported in every positionformat: "date" and a description

The full list of supported keywords is in JSON output.

Was this page helpful?