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

# Structured outputs

> Get the answer as JSON that matches your schema, ready to parse in your code.

Give the model a JSON schema and it answers with a JSON object that follows it. Your code parses the answer instead of pulling fields out of free text.

> [tab] Responses
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import json
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> response = client.responses.create(
>     model="deepseek-v4.1-flash",
>     input="Name one European capital and its country.",
>     text={
>         "format": {
>             "type": "json_schema",
>             "name": "capital",
>             "strict": True,
>             "schema": {
>                 "type": "object",
>                 "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
>                 "required": ["city", "country"],
>                 "additionalProperties": False,
>             },
>         }
>     },
> )
>
> print(json.loads(response.output_text))
> ```
>
> ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import OpenAI from "openai";
>
> const client = new OpenAI({ baseURL: "https://api.naga.ac/v1", apiKey: process.env.NAGA_API_KEY });
>
> const response = await client.responses.create({
>   model: "deepseek-v4.1-flash",
>   input: "Name one European capital and its country.",
>   text: {
>     format: {
>       type: "json_schema",
>       name: "capital",
>       strict: true,
>       schema: {
>         type: "object",
>         properties: { city: { type: "string" }, country: { type: "string" } },
>         required: ["city", "country"],
>         additionalProperties: false,
>       },
>     },
>   },
> });
>
> console.log(JSON.parse(response.output_text));
> ```
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> curl https://api.naga.ac/v1/responses \
>   -H "Authorization: Bearer $NAGA_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "model": "deepseek-v4.1-flash",
>     "input": "Name one European capital and its country.",
>     "text": {
>       "format": {
>         "type": "json_schema",
>         "name": "capital",
>         "strict": true,
>         "schema": {
>           "type": "object",
>           "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
>           "required": ["city", "country"],
>           "additionalProperties": false
>         }
>       }
>     }
>   }'
> ```

> [tab] Chat Completions
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import json
> import os
> from openai import OpenAI
>
> client = OpenAI(base_url="https://api.naga.ac/v1", api_key=os.environ["NAGA_API_KEY"])
>
> completion = client.chat.completions.create(
>     model="deepseek-v4.1-flash",
>     messages=[{"role": "user", "content": "Name one European capital and its country."}],
>     response_format={
>         "type": "json_schema",
>         "json_schema": {
>             "name": "capital",
>             "strict": True,
>             "schema": {
>                 "type": "object",
>                 "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
>                 "required": ["city", "country"],
>                 "additionalProperties": False,
>             },
>         },
>     },
> )
>
> print(json.loads(completion.choices[0].message.content))
> ```
>
> ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import OpenAI from "openai";
>
> const client = new OpenAI({ baseURL: "https://api.naga.ac/v1", apiKey: process.env.NAGA_API_KEY });
>
> const completion = await client.chat.completions.create({
>   model: "deepseek-v4.1-flash",
>   messages: [{ role: "user", content: "Name one European capital and its country." }],
>   response_format: {
>     type: "json_schema",
>     json_schema: {
>       name: "capital",
>       strict: true,
>       schema: {
>         type: "object",
>         properties: { city: { type: "string" }, country: { type: "string" } },
>         required: ["city", "country"],
>         additionalProperties: false,
>       },
>     },
>   },
> });
>
> console.log(JSON.parse(completion.choices[0].message.content));
> ```
>
> ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> curl https://api.naga.ac/v1/chat/completions \
>   -H "Authorization: Bearer $NAGA_API_KEY" \
>   -H "Content-Type: application/json" \
>   -d '{
>     "model": "deepseek-v4.1-flash",
>     "messages": [{"role": "user", "content": "Name one European capital and its country."}],
>     "response_format": {
>       "type": "json_schema",
>       "json_schema": {
>         "name": "capital",
>         "strict": true,
>         "schema": {
>           "type": "object",
>           "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
>           "required": ["city", "country"],
>           "additionalProperties": false
>         }
>       }
>     }
>   }'
> ```

> [tab] Messages
>
> ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import json
> import os
> from anthropic import Anthropic
>
> client = Anthropic(base_url="https://api.naga.ac", api_key=os.environ["NAGA_API_KEY"])
>
> message = client.messages.create(
>     model="claude-haiku-4.5",
>     max_tokens=1024,
>     messages=[{"role": "user", "content": "Name one European capital and its country."}],
>     output_config={
>         "format": {
>             "type": "json_schema",
>             "schema": {
>                 "type": "object",
>                 "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
>                 "required": ["city", "country"],
>                 "additionalProperties": False,
>             },
>         }
>     },
> )
>
> text = "".join(block.text for block in message.content if block.type == "text")
> print(json.loads(text))
> ```
>
> ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
> import Anthropic from "@anthropic-ai/sdk";
>
> const client = new Anthropic({ baseURL: "https://api.naga.ac", apiKey: process.env.NAGA_API_KEY });
>
> const message = await client.messages.create({
>   model: "claude-haiku-4.5",
>   max_tokens: 1024,
>   messages: [{ role: "user", content: "Name one European capital and its country." }],
>   output_config: {
>     format: {
>       type: "json_schema",
>       schema: {
>         type: "object",
>         properties: { city: { type: "string" }, country: { type: "string" } },
>         required: ["city", "country"],
>         additionalProperties: false,
>       },
>     },
>   },
> });
>
> for (const block of message.content) {
>   if (block.type === "text") console.log(JSON.parse(block.text));
> }
> ```

The answer is a JSON string such as `{"city": "Lisbon", "country": "Portugal"}`, which the example parses and prints.

## Schema options in each format

Each format puts the schema in its own field and returns the JSON in its own place:

| | Responses | Chat Completions | Messages |
| - | - | - | - |
| JSON that follows a schema | `text: {"format": {"type": "json_schema", "name", "schema", "strict"}}` | `response_format: {"type": "json_schema", "json_schema": {"name", "schema", "strict"}}` | `output_config: {"format": {"type": "json_schema", "schema"}}` |
| Any JSON object | `text: {"format": {"type": "json_object"}}` | `response_format: {"type": "json_object"}` | Not available |
| Where the JSON is | `response.output_text` | `choices[0].message.content` | The first `text` block |

JSON mode, `json_object`, asks for valid JSON without a schema. Say in the prompt that you want JSON when you use it, since some models need the hint.

The SDK helpers `client.responses.parse()` and `client.chat.completions.parse()` build the same request from a Pydantic or Zod model, and they work against NagaAI too.

## Models without schema support

Check `parameters` of the model's `chat` operation in [`/v1/models`](https://docs.naga.ac/get-started/models) for `response_format`. The list covers every provider that serves the model, so the provider that takes a given request can still lack schema support. In that case NagaAI asks the provider for JSON mode and adds your schema to the prompt. The answer is still JSON, but nothing guarantees it follows the schema, so validate it in your code before you use it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.