> ## Documentation Index
> Fetch the complete documentation index at: https://docs.layerx1.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured output.

> When downstream code parses the answer, ask for the shape up front. Three patterns, strongest first: a JSON schema, plain JSON mode, or a tool schema on the Messages dialect.

## JSON schema (recommended)

On [Chat Completions](/api/chat-completions), pass
`response_format.type: "json_schema"` with your schema. The response content is a single
JSON document conforming to it — parse and go.

<CodeGroup>
  ```sh curl theme={null}
  curl https://api.layerx1.com/v1/chat/completions \
    -H "authorization: Bearer $LAYERX1_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "model": "lx1-gpt-oss-120b",
      "messages": [{ "role": "user", "content": "Extract: Ada Lovelace, born 1815." }],
      "response_format": {
        "type": "json_schema",
        "json_schema": {
          "name": "person",
          "strict": true,
          "schema": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "birth_year": { "type": "integer" }
            },
            "required": ["name", "birth_year"],
            "additionalProperties": false
          }
        }
      }
    }'
  ```

  ```python Python theme={null}
  r = client.chat.completions.create(
      model="lx1-gpt-oss-120b",
      messages=[{"role": "user", "content": "Extract: Ada Lovelace, born 1815."}],
      response_format={
          "type": "json_schema",
          "json_schema": {
              "name": "person",
              "strict": True,
              "schema": {
                  "type": "object",
                  "properties": {
                      "name": {"type": "string"},
                      "birth_year": {"type": "integer"},
                  },
                  "required": ["name", "birth_year"],
                  "additionalProperties": False,
              },
          },
      },
  )
  person = json.loads(r.choices[0].message.content)
  ```

  ```ts TypeScript theme={null}
  const r = await client.chat.completions.create({
    model: "lx1-gpt-oss-120b",
    messages: [{ role: "user", content: "Extract: Ada Lovelace, born 1815." }],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "person",
        strict: true,
        schema: {
          type: "object",
          properties: {
            name: { type: "string" },
            birth_year: { type: "integer" },
          },
          required: ["name", "birth_year"],
          additionalProperties: false,
        },
      },
    },
  });
  const person = JSON.parse(r.choices[0].message.content ?? "{}");
  ```
</CodeGroup>

```json title="Response content" theme={null}
{ "name": "Ada Lovelace", "birth_year": 1815 }
```

## JSON mode

When any valid JSON is enough and the exact shape can flex, use
`{ "type": "json_object" }` and describe the fields you want in the prompt:

```json theme={null}
{ "response_format": { "type": "json_object" } }
```

Guaranteed parseable, not guaranteed shaped — validate before trusting field names.

## On the Messages dialect

The Anthropic dialect expresses shapes through tools: define a tool whose `input_schema`
is your output schema and force it with `tool_choice` — the arguments of the resulting
`tool_use` block are your structured output.

```json title="Force the 'record_person' tool" theme={null}
{
  "tools": [{
    "name": "record_person",
    "description": "Record the extracted person",
    "input_schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "birth_year": { "type": "integer" }
      },
      "required": ["name", "birth_year"]
    }
  }],
  "tool_choice": { "type": "tool", "name": "record_person" }
}
```

## Practical notes

* Set `strict: true` and `additionalProperties: false` — schemas that forbid extras fail
  loud instead of drifting quietly.
* Keep schemas shallow. Deeply nested optional trees invite empty objects; several flat
  calls beat one cathedral schema.
* Reasoning models produce excellent structured output but budget `max_tokens` generously
  — hidden reasoning counts against it before the JSON is emitted.
* Always validate before acting — a `400` on an impossible constraint or a truncated
  `length` finish is recoverable if you check for it ([Errors](/errors)).
