Structured output
Ask for JSON or a schema-conforming object with responseFormat — a Pro feature. JSON mode, JSON Schema, what each provider guarantees, and the Anthropic caveat.
Pro Structured output asks the model to return valid JSON — either a
free-form JSON object, or an object conforming to a JSON Schema you supply. Set it
with responseFormat on any chat() call.
Structured output is a Pro feature on any provider — set a licenseKey and
call await ai.init() first. Any responseFormat other than "text" triggers
the gate. See Free vs. Pro.
JSON object mode
responseFormat: "json" asks for a valid JSON object.
const res = await ai.chat({
provider: "openai",
messages: [
{ role: "system", content: "Extract the person as JSON." },
{ role: "user", content: "Ada Lovelace, born 1815, mathematician." },
],
responseFormat: "json",
});
const person = JSON.parse(res.content); // { name: "Ada Lovelace", born: 1815, ... }JSON Schema mode
For a specific shape, pass { type: "json_schema", schema }. Where the provider
supports it, Radon upgrades this to strict schema enforcement.
const res = await ai.chat({
provider: "openai",
messages: [{ role: "user", content: "Ada Lovelace, born 1815, mathematician." }],
responseFormat: {
type: "json_schema",
name: "person",
schema: {
type: "object",
properties: {
name: { type: "string" },
born: { type: "number" },
field: { type: "string" },
},
required: ["name", "born", "field"],
},
},
});type"json_schema"requiredSelects schema mode.
schemaJSONSchemarequiredThe JSON Schema the output must conform to.
namestringdefault: "response"A name for the schema (used by providers that require one).
strictbooleandefault: trueRequest strict enforcement where the provider supports it.
What each provider guarantees
This is the least-uniform capability across providers, so normalization is best-effort with documented guarantees — not a promise of identical behavior.
OpenAI, Gemininative schema enforcementThe strongest guarantee. json_schema maps to OpenAI's
response_format.json_schema (strict) and Gemini's responseSchema +
responseMimeType.
Groq, Mistral, DeepSeek, OpenRouter, xAI, Together, OllamaJSON-object moderesponseFormat: "json" maps to response_format: { type: "json_object" }.
Full JSON-schema enforcement varies by provider and model; where
unsupported, you get JSON-object mode and should validate the shape yourself.
Anthropicbest-effort via system instructionSee the caveat below.
Anthropic has no response_format parameter
Anthropic's Messages API has no response_format. For a JSON request, Radon
appends a system instruction ("respond with a single valid JSON value and
nothing else…", including the schema when you provide one). This is best-effort —
the model is asked, not forced.
For a hard guarantee on Anthropic, force a tool instead: define a tool whose
parameters is your schema and set toolChoice: { name: "your_tool" }. The tool
call's arguments is then your validated object.
const res = await ai.chat({
provider: "anthropic",
messages: [{ role: "user", content: "Ada Lovelace, born 1815, mathematician." }],
tools: [{
name: "emit_person",
description: "Return the extracted person.",
parameters: {
type: "object",
properties: {
name: { type: "string" },
born: { type: "number" },
field: { type: "string" },
},
required: ["name", "born", "field"],
},
}],
toolChoice: { name: "emit_person" },
});
const person = res.toolCalls[0]?.arguments; // a parsed, schema-shaped objectAlways validate untrusted output
Even with strict schema modes, validate the parsed object against your own types (e.g. with Zod) before trusting it — models can still surprise you, and JSON-object mode makes no schema promise at all.
Next steps
Vision
Send images to multimodal models with content parts — a Pro feature. URL vs. inline base64, the Gemini URL caveat, and choosing a vision-capable model.
Fallback chains
Automatically retry a failed chat() on backup providers — a Pro feature. How the chain works, which errors stop it, and why streaming doesn't support it.