# Structured output

[Open models](https://www.rightnowai.co/docs/open-models) / [Structured output](https://www.rightnowai.co/docs/open-models/guides/structured-output)

Updated 2026-11-11

Pass a `response_format` and the model is constrained toward your JSON Schema during generation. Use it for anything downstream that needs a known shape: database inserts, form filling, data extraction, classification with fixed enums.

**Connection**

| Connection | Value |
| --- | --- |
| API base | `https://api.runinfra.ai/v1` |
| Workspace key | `rp_...` |
| Process variable | `RUNINFRA_GATEWAY_KEY` |
| Billing | The existing funding rules of your open-model account. |

Replace `MODEL_ID` with an available id from [Open models](https://runinfra.ai/inference-api?utm_source=rightnowai.co&utm_medium=referral&utm_content=docs-open-models); read current capabilities, limits and prices from `GET /v1/models`.

## Minimal code

These examples use `reasoning_effort: "none"` so the selected model can enforce the schema without generating reasoning first. Choose a model that supports JSON output and disabling reasoning. A model that is temporarily paused is reported in `GET /v1/models` and on its model page.

**cURL**

```shell
curl https://api.runinfra.ai/v1/chat/completions \
  -H "Authorization: Bearer $RUNINFRA_GATEWAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MODEL_ID",
    "messages": [
      {"role":"system","content":"Extract the receipt fields."},
      {"role":"user","content":"I bought coffee and a muffin at Blue Bottle on 2026-04-20 for $12.50"}
    ],
    "reasoning_effort": "none",
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "receipt",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "merchant":  {"type":"string"},
            "total_usd": {"type":"number"},
            "date":      {"type":"string"},
            "items":     {"type":"array","items":{"type":"string"}}
          },
          "required": ["merchant","total_usd","date","items"],
          "additionalProperties": false
        }
      }
    }
  }'
```

**Python**

```python
import os
from openai import OpenAI
from pydantic import BaseModel

client = OpenAI(
    base_url="https://api.runinfra.ai/v1",
    api_key=os.environ["RUNINFRA_GATEWAY_KEY"],
)

class Receipt(BaseModel):
    merchant: str
    total_usd: float
    date: str
    items: list[str]

response = client.beta.chat.completions.parse(
    model="MODEL_ID",
    messages=[
        {"role": "system", "content": "Extract the receipt fields."},
        {"role": "user", "content": "I bought coffee and a muffin at Blue Bottle on 2026-04-20 for $12.50"},
    ],
    reasoning_effort="none",
    response_format=Receipt,
)

receipt: Receipt = response.choices[0].message.parsed
print(receipt.merchant, receipt.total_usd)
```

**TypeScript**

```typescript
import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI({
  baseURL: "https://api.runinfra.ai/v1",
  apiKey: process.env.RUNINFRA_GATEWAY_KEY,
});

const Receipt = z.object({
  merchant: z.string(),
  total_usd: z.number(),
  date: z.string(),
  items: z.array(z.string()),
});

const response = await client.chat.completions.parse({
  model: "MODEL_ID",
  messages: [
    { role: "system", content: "Extract the receipt fields." },
    { role: "user", content: "I bought coffee and a muffin at Blue Bottle on 2026-04-20 for $12.50" },
  ],
  reasoning_effort: "none",
  response_format: zodResponseFormat(Receipt, "receipt"),
});

const receipt = response.choices[0].message.parsed;
console.log(receipt?.merchant, receipt?.total_usd);
```

The SDK `parse()` helpers validate the reply against your Pydantic or Zod model. The curl tab shows the raw `response_format` request underneath them, which is the portable form for any client.

## Which model, and what it needs

On some models, the gateway applies `reasoning_effort: "none"` when you omit it beside a schema. The [model-specific source reference](https://runinfra.ai/docs/api-reference/chat-completions?utm_source=rightnowai.co&utm_medium=referral&utm_content=docs-open-models) identifies the affected models; this exception is not a discovery field. The response header `X-RunInfra-Reasoning-Effort-Applied` reports the effort applied when the request did not name one.

If you explicitly send an incompatible effort, the request is refused with `400`, `param: "response_format"`. Read [Chat completions](https://www.rightnowai.co/docs/open-models/chat-completions#three-things-a-request-can-be-refused-for) for model-specific behavior.

## What to tune

**Reference 124**

| Parameter | Effect |
| --- | --- |
| `response_format: { type: "json_object" }` | Looser. Any valid JSON, no schema enforcement. |
| `response_format.json_schema.strict: true` | Accepted for Compatible clients. The Pydantic and Zod helpers set it for you. |
| `temperature: 0` | Best for deterministic extraction. Non-zero works too. |
| `reasoning_effort: "none"` | Lets a model that supports disabling reasoning enforce a schema without reasoning tokens. |

## Common mistakes

- **Asking for JSON in the prompt instead of in `response_format`.** The model can still add commentary or markdown fences. Pass the field.
- **Leaving `additionalProperties` open.** Without `additionalProperties: false`, the reply may carry keys you did not declare. The helpers set it. Raw JSON Schema users must add it.
- **Nested `anyOf` without discriminators.** Use enums or discriminated unions. An unbounded `anyOf` gives the schema too little shape to enforce.
- **Expecting enums to be case-insensitive.** Schema enums are exact match. `"Paris"` does not satisfy `enum: ["paris", "berlin"]`.

## Next steps

[### Tool calling Structured arguments, then an action.](https://www.rightnowai.co/docs/open-models/guides/tool-calling) [### Streaming Stream the reply as it is generated.](https://www.rightnowai.co/docs/open-models/guides/streaming) [### Chat completions The full `response_format` contract.](https://www.rightnowai.co/docs/open-models/chat-completions)

[Source reference](https://runinfra.ai/docs/cookbook/structured-output?utm_source=rightnowai.co&utm_medium=referral&utm_content=docs-open-models)

## Next

[Prompt caching for agents](https://www.rightnowai.co/docs/open-models/guides/prompt-caching)
