Why structured outputs?
Raw AI responses are unpredictable. Different providers return different formats, and even the same model can vary between requests. Structured outputs solve this by enforcing a JSON schema on every response, giving your application a contract it can rely on.
How it works
- Define a schema: Create a JSON schema in the ModelRiver console under Structured Outputs.
- Attach to a workflow: Link the schema to one or more workflows.
- Automatic validation: ModelRiver validates each AI response (for sync and async requests) against your schema. If the output is empty or doesn't match the schema, that attempt fails with
empty_structured_outputorinvalid_structured_output. ModelRiver never fills in missing fields or rewrites the output. - Provider failover: If a provider is down, times out, rate-limits the request, or returns output that fails schema validation, ModelRiver tries your configured backup models. If every attempt fails, the request returns an error (
status: "error"). ModelRiver never invents a response.
Creating a structured output
- Navigate to Structured Outputs in your project sidebar
- Click Create Structured Output
- Define your JSON schema with required fields, types, and descriptions
- Add sample data that conforms to the schema (used for test mode)
- Save and attach to workflows
Schema example
JSON
1{2 "type": "object",3 "required": ["summary", "sentiment", "category"],4 "properties": {5 "summary": {6 "type": "string",7 "description": "A concise summary of the input"8 },9 "sentiment": {10 "type": "string",11 "enum": ["positive", "negative", "neutral"],12 "description": "Overall sentiment classification"13 },14 "category": {15 "type": "string",16 "description": "Topic category of the content"17 },18 "confidence": {19 "type": "number",20 "minimum": 0,21 "maximum": 1,22 "description": "Model confidence score"23 }24 }25}Supported schema keywords
patternandpatternPropertiesare not supported; schemas that use them are rejected when you save them.format(for example"format": "email"or"format": "date") is accepted but not enforced during validation. Treat it as a hint to the model and check formats in your application if they matter.
Best practices
- Include examples in the schema to guide providers. ModelRiver passes these as context to improve compliance.
- Start simple: Begin with a minimal schema and add fields as your application matures.
- Use enums for categorical fields to constrain values and reduce parsing errors.
- Monitor validation: Check Observability for validation failure rates and adjust schemas accordingly.
- Configure backups: Add backup models from a different provider so a single provider outage does not fail the request.
When every provider fails
If the primary model and all backup models fail, ModelRiver returns an error with meta.attempts listing each provider, model, and failure. It does not fill in placeholder or sample data, so any successful response contains output produced by a model.
- Handle the error in your application, for example by retrying later or showing a "try again" message
- Use test mode when you want sample data without calling a provider
Next steps
- Type-safe AI Solution: Why and how to use structured data in production.
- Test mode: Use sample data to validate integrations
- Build a workflow: Attach structured outputs to workflows
- Import & export: Move structured outputs with their workflow configuration
- API response formats: Understand response structure