Eterial Docs
API reference

Structured outputs

Getting JSON back, and how much of a guarantee that is.

response_format is passed to the model as you send it, in both its forms:

{ "response_format": { "type": "json_object" } }
{
  "response_format": {
    "type": "json_schema",
    "json_schema": { "name": "invoice", "schema": { "...": "..." }, "strict": true }
  }
}

This is not a guarantee we make

Eterial does not validate the response against your schema, and does not re-prompt when a model ignores it. Whatever enforcement you get comes from the model that served the request — so the same request can be strictly conformant on one day and merely well-intentioned on another, since the backend serving a model is not fixed. See Routing.

The reliable way to get a typed object

Ask for it as a tool. A function with a parameter schema is understood by every model that supports tools, and the arguments come back as a JSON string built against that schema:

tools = [{
    "type": "function",
    "function": {
        "name": "emit_invoice",
        "parameters": {
            "type": "object",
            "properties": {
                "total": {"type": "number"},
                "currency": {"type": "string"},
            },
            "required": ["total", "currency"],
        },
    },
}]

response = client.chat.completions.create(
    model="minimax-m2.7",
    messages=[{"role": "user", "content": invoice_text}],
    tools=tools,
    tool_choice={"type": "function", "function": {"name": "emit_invoice"}},
)

data = json.loads(response.choices[0].message.tool_calls[0].function.arguments)

Forcing tool_choice to that function removes the model's option to answer in prose at all. See Tool calling.

Either way, validate

Parse into a schema you own — Pydantic, Zod, whatever your stack uses — and treat a parse failure as a normal, expected outcome rather than an exception. Retrying once on a failure costs less than a schema violation reaching your database.

On this page