Skip to content
All guides

Extract structured data (JSON)

Strict structured output makes the model return JSON that matches your schema every time: right fields, right types, no extra text. It is the simplest way to put AI into a pipeline, CRM or spreadsheet.

Recommended models

Chosen from models whose abilities we have verified for this job. Cost is for one email or form (about 600 tokens in, 120 out), at current prices.

ModelInput / 1MOutput / 1MContextPer request
Our pickDeepSeek V4.1 Flash
deepseek/deepseek-v4.1-flash
$0.375$1.501.05M$0.000405
Also strongGLM 5.3 Flash
z-ai/glm-5.3-flash
$0.1875$0.6251.05M$0.000188
Lowest costgpt-oss-20b
openai/gpt-oss-20b
$0.0625$0.5625128K$0.000105

How it works

  1. 1Describe the fields you want as a JSON Schema. List every field in required and set additionalProperties to false.
  2. 2For values that may be missing, ask for an empty string or 0 instead of leaving the field out.
  3. 3Send response_format with type json_schema and strict: true, then parse the reply with JSON.parse or json.loads.

Copy, paste, run

Set AMR_API_KEY to a key from your dashboard, install the OpenAI SDK (pip install openai or npm install openai) and run it. Swap the model for any other in the table.

import json
import os

from openai import OpenAI

client = OpenAI(base_url="https://api.aimodelsrouter.ai/v1", api_key=os.environ["AMR_API_KEY"])
MODEL = "deepseek/deepseek-v4.1-flash"

# Describe exactly the fields you want. With "strict": True the reply always matches this schema.
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "email": {"type": "string", "description": "Empty string if not given"},
        "company": {"type": "string", "description": "Empty string if not given"},
        "seats": {"type": "integer", "description": "0 if not given"},
        "intent": {"type": "string", "enum": ["sales", "support", "billing", "other"]},
    },
    "required": ["name", "email", "company", "seats", "intent"],
    "additionalProperties": False,
}

message = "Hi, I'm Dana Ruiz from Northwind Traders (dana@northwind.example). Could we get a quote for 50 seats?"

response = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "Extract the requested fields from the customer's message."},
        {"role": "user", "content": message},
    ],
    response_format={"type": "json_schema", "json_schema": {"name": "lead", "strict": True, "schema": schema}},
)
lead = json.loads(response.choices[0].message.content)
print(lead)  # {'name': 'Dana Ruiz', 'email': 'dana@northwind.example', 'company': 'Northwind Traders', ...}

Tested 2026-10-28: both versions were run against the live API with each model recommended at the time, and their answers checked.

Tips

  • Only models listed with Structured outputs on their page guarantee the schema; we verify this on every model before listing it.
  • Enums (a fixed list of allowed values) make classification-style fields reliable.
  • Batch many small documents through concurrent requests instead of one huge prompt, so one bad document cannot spoil the rest.
All 26 models that fit this job