Atlas Inference

Structured outputs

Constrain a completion to a JSON Schema you supply, and get content that validates against it.

Send response_format: {"type": "json_schema", ...} and the returned content parses as JSON and validates against your schema. If it does not, you get an error — never unvalidated content presented as a success.

Supported on atlas-small-1, atlas-mid-1, and atlas-large-1. Not supported on atlas-code-1. Check capabilities.structured_output on GET /v1/models.

Making a request

The schema lives at response_format.json_schema.schema — the Chat Completions nesting, not the Responses API's text.format.schema.

strict defaults to on. Omitting it, or sending strict: true, both get the full subset treatment. Only an explicit strict: false opts out of the strictness flag — but the schema is still validated against the subset either way, because a schema accepted loosely is a schema nothing enforces.

Three rules your schema must follow

Beyond the keyword subset, strict mode imposes three structural rules. They are OpenAI's strict-mode rules, and they catch most first-time failures:

The root must be an object schema

Not an array, not a string. Wrap a list in an object with a single property. Violation code: root_not_object.

Every property must be listed in `required`

There are no optional properties. To model "may be absent", give the property a type union including null and require it. Violation code: optional_property.

Every object must set `additionalProperties: false`

At every level, not just the root. Violation code: additional_properties.

Nesting is limited to 5 levels, and $ref must be a local #/$defs/<name> pointer that resolves within the same document.

When a schema is rejected

A schema outside the subset is refused at validation, before the request is admitted — you are never charged for a request whose schema could not have been enforced, and you never receive unvalidated content in its place.

{
  "error": {
    "message": "the keyword 'pattern' is not in this subset; ...",
    "type": "invalid_request_error",
    "param": "response_format.json_schema.schema",
    "code": "unsupported_json_schema",
    "request_id": "req_01k4v9m2..."
  }
}

The message names the offending keyword and its RFC 6901 pointer into your schema document, so the fix is mechanical. See the subset reference for the full keyword lists and every violation code.

When the output does not validate

Content is checked against your schema after generation. Two failures are possible, and both are distinguishable from a schema you got wrong:

structured_output_not_jsonerror code

The model's content did not parse as JSON at all.

structured_output_schema_violationerror code

The content parsed, but did not validate against the schema you supplied.

On a streamed request, the check runs on the assembled content — so the deltas are delivered first, and then the stream terminates with an in-band error frame and no [DONE]. Your accumulated content is the invalid document; do not treat it as a completed generation. See Streaming.

Generating a schema from your types

Most schema generators emit keywords outside the subset by default. Two notes:

  • Pydantic / zod: emit $defs and $ref, which are supported. They also emit constraints like minLength, pattern, and minimum, which are not. Strip them before sending, or express those bounds in the prompt and validate them yourself after parsing.
  • default is accepted, so a zod .default() does not break the schema. It is carried as an annotation and never enforced — it constrains no instance's validity.

Not the same as tool schemas

A tool's function.parameters document is not validated against this subset — it is passed through to the backend as you send it. Only response_format.json_schema.schema is checked. See Tool calling.

On this page