Trang này chưa được dịch sang Tiếng Việt. Đang hiển thị bản gốc tiếng Anh.

Structured outputs

Pinning the response shape with a JSON schema

response_format lets you ask a model to return JSON that matches a schema you define, instead of free-form text. This is worth reaching for whenever your code parses the reply — it removes an entire class of "the model wrapped it in markdown" or "it invented an extra field" bugs.

Using it

Set type to json_schema and give the schema a name:

json
{
  "model": "google/gemma-4-26b-a4b",
  "messages": [
    { "role": "user", "content": "Extract the city and temperature: it's 21°C in Busan today." }
  ],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "weather",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "city": { "type": "string" },
          "temperature_c": { "type": "number" }
        },
        "required": ["city", "temperature_c"],
        "additionalProperties": false
      }
    }
  }
}

The reply's message.content is a JSON string matching the schema:

json
{ "city": "Busan", "temperature_c": 21 }

It is still a string — JSON.parse it yourself. We do not decode it for you, because doing so would silently swallow the case where the model produced invalid JSON.

Model support

Both of our catalog models list response_format in supported_parameters:

bash
curl -s "https://openrouter.myip.co.kr/api/v1/models" | jq '.data[] | {id, supported_parameters}'

Sending response_format to a model whose supported_parameters does not include it is not blocked here — the serving engine decides whether to honour it, ignore it, or error. To have unsupported candidates filtered out of the chain instead of silently answering with plain text, set provider.require_parameters: true (see Provider routing).

Streaming

response_format works the same way with stream: true. The model streams the JSON text token by token in delta.content; concatenate the deltas and parse once finish_reason arrives, the same as you would for any streamed text. See Streaming.

typescript
let json = '';
for await (const chunk of stream) {
  json += chunk.choices[0]?.delta?.content ?? '';
}
const data = JSON.parse(json);

Do not try to JSON.parse a partial buffer on every chunk — it is not valid JSON until the stream ends.

A full example

curl https://openrouter.myip.co.kr/api/v1/chat/completions \
  -H "Authorization: Bearer $MYIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemma-4-26b-a4b",
    "messages": [
      {"role": "user", "content": "Extract the city and temperature: it'\''s 21°C in Busan today."}
    ],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "weather",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "city": {"type": "string"},
            "temperature_c": {"type": "number"}
          },
          "required": ["city", "temperature_c"],
          "additionalProperties": false
        }
      }
    }
  }'

Best practices

  1. Write descriptions into the schema. "description": "ISO 4217 currency code" on a property guides the model more than the field name alone.
  2. Use strict: true whenever the engine you are calling supports it, and treat conformance as "usually" rather than "always" until you have tested that specific model.
  3. Keep schemas flat where you can. Deep nesting and unusual JSON Schema features (oneOf, $ref) are more likely to be only partially supported by a given engine's strict mode.
  4. Validate anyway. Parse the string, then validate it against your schema in your own code (e.g. with ajv or zod) before trusting it. response_format reduces malformed output; it does not eliminate the need to handle it.

Errors

SituationWhat happens
Model does not support response_formatEngine-dependent — usually the field is ignored and you get plain text back, not an error
json_schema is not valid JSON SchemaThe upstream call fails; surfaces as 502 provider_error with the upstream's message in metadata
Model returns text that does not match the schema despite strict: trueNot caught by us — validate the parsed object yourself

See Errors and debugging for the general error envelope.

Cập nhật lần cuối 5 thg 9, 2026