Guides
Structured output
Ask for JSON that matches a schema, then validate it anyway.
response_format: { type: "json_schema" } is honoured natively where the provider supports it and degraded elsewhere (schema appended to the prompt plus validation on the way out, warning feature_degraded). x-aiml-warnings says which happened.
import OpenAI from "openai";
const client = new OpenAI({ baseURL: (process.env.AIML_BASE_URL ?? "https://api.ai.ml") + "/v1", apiKey: process.env.AIML_API_KEY });
const schema = {
type: "object",
properties: { city: { type: "string" }, population_millions: { type: "number" } },
required: ["city", "population_millions"],
additionalProperties: false,
};
const completion = await client.chat.completions.create({
model: process.env.AIML_MODEL ?? "openai/gpt-5-mini",
messages: [{ role: "user", content: "Give the largest city in India as JSON. JSON_SCHEMA" }],
response_format: { type: "json_schema", json_schema: { name: "city", schema, strict: true } },
});
const raw = completion.choices[0]?.message.content ?? "";
let ok = false;
try {
const parsed = JSON.parse(raw) as { city?: unknown; population_millions?: unknown };
ok = typeof parsed.city === "string" && typeof parsed.population_millions === "number";
} catch {
ok = false;
}
console.log(raw);
console.log(`schema_ok=${ok}`);What the gateway does with the schema
- Normalises it. Local
definitionsbecome$defs, keywords no provider accepts ($dynamicRef,unevaluatedProperties) are rejected withschema_invalid, and keywords a particular provider rejects (patternPropertieson strict decoders) are dropped with aschema_rewrittenwarning. - Strict subset. With
strict: trueevery property becomes required (optional ones turn nullable),additionalPropertiesis set tofalseeverywhere and a rootoneOfbecomesanyOf; the rewrites are listed in theschema_rewrittenwarning. - Picks the mechanism per endpoint. Native constrained decoding where the catalog says so (OpenAI
response_format, Anthropicoutput_format, GeminiresponseJsonSchema), tool-forcing on Anthropic endpoints without native support (anemit_outputtool whose call is returned to you as text; extended thinking is dropped with a warning),guided_jsonon vLLM-style hosts, and a prompt suffix everywhere else. The warningfeature_degradedsays which emulation ran. - Validates the answer. Every response is validated against the schema in the gateway. A non-conforming answer ends with stop reason
schema_violationand aschema_violationwarning naming the failing paths. Non-streaming requests get one corrective retry against the same endpoint (both calls are billed; theschema_retriedwarning marks it) unlessaiml.route.schema_retryisoff; streams cannot be retried and report the violation on the final chunk.
Validate on your side regardless: strict: true is a contract with the provider, not a guarantee across every model, and the gateway never rewrites model output.
JSON_SCHEMA in the prompt is a hint for the mock provider; drop it in production prompts.