For /v1/responses, see Using the Responses API. The other examples on this page use Chat Completions.
What is structured outputs?
Structured outputs constrain a model-generated response to a JSON Schema that you provide. Instead of describing the desired shape in the prompt and hoping the model complies, you pass the schema in response_format, and the reply comes back as valid JSON that matches it β the same field names, the same types, and only the values the schema allows. The result is safe to parse, but schema validity does not make its values trusted. Validate domain rules, escape content for its destination, and enforce authorization before using the values in UI, storage, or external actions.
Choose an output mode
| JSON mode | Structured outputs | |
|---|---|---|
response_format | {"type": "json_object"} | {"type": "json_schema", ...} |
| Output is valid JSON | β Yes | β Yes |
| Output follows your schema | β No | β Yes |
| Schema required | β No | β Yes |
Prompt must contain the word JSON | β Yes | β No |
Use structured outputs whenever your application depends on fixed fields, types, or enum values. JSON mode only guarantees that the output parses as JSON β the field names, types, and nesting can differ from one call to the next, so you still have to validate what comes back.
JSON mode also requires the word JSON to appear somewhere in the conversation. If it does not, the request returns an HTTP 400 error.
Defining schemas
Structured outputs support a subset of the JSON Schema specification, matching the subset used by OpenAI Structured Outputs.
Requirements
- The supported types are
string,number,integer,boolean,object, andarray. - The root of the schema must be an
object. - Every property must be listed in the
requiredarray. - To represent an optional value, keep the key in
requiredand addnullto its type β for example,"type": ["string", "null"]. The key is always present in the response; its value can benull. strictmust be set totrue.additionalPropertiesmust be set tofalseon every object.- Objects can nest up to 10 levels deep.
$defsand$refare supported across all current aliases, and are the recommended way to reuse a subschema. Only local references of the form#/$defs/<name>are accepted.
Not supported
- The composition keywords outside the OpenAI subset β
allOf,oneOf,not,dependentRequired,dependentSchemas, andif/then/else. patternProperties.- Recursive
$ref, including a self-reference to the schema root ({"$ref": "#"}). Any reference other than a local#/$defs/<name>is rejected with an HTTP 400 error, so flatten recursive structures to a fixed depth instead.
Avoid for cross-model compatibility
Nested anyOf is not reliable across all current aliases, so avoid it if your application has to work on more than one model. Express alternatives with an enum or a set of nullable fields instead of composition keywords.
Make a structured request
Classify a support ticket and draft a reply in a single solar-pro4 call. Because the schema pins category to three known values, the response is always one of billing, technical, or account β never a synonym the model chose on its own.
Understand the response
The raw Chat Completions response carries the generated JSON as a string in choices[0].message.content, not as an already-parsed object. Anything that speaks the OpenAI-compatible API sees that string: the Python OpenAI, JavaScript, cURL, and LlamaIndex examples above parse it themselves β json.loads in Python, JSON.parse in JavaScript. LangChain is the exception, because with_structured_output parses the string for you and hands back an object.
Check choices[0].finish_reason before parsing. A value of stop means the model finished the object and the content is complete JSON. A value of length means generation hit the token limit and the content is cut off mid-object, so parsing it will fail. Handle that case by raising max_tokens or retrying, rather than by parsing the truncated text.
Stream structured output
Set stream to true to receive the JSON as it is generated. The response arrives as fragments of JSON text in choices[0].delta.content, not as partial objects β each fragment is a piece of the string, so an individual delta is usually not valid JSON on its own. Accumulate every delta into a single string and parse it only after the stream finishes.
If you read the raw SSE stream instead of using an SDK, the stream ends with a data: [DONE] line.
Using the Responses API
The Responses API is available on Solar Pro 4 and Solar Mini 4.
Use the flat text.format object to define a JSON Schema. The SDK exposes the generated JSON string as response.output_text.