← Back to docs

Recipe

Structured extraction with JSON schema

Coerce any free-form input (invoices, contracts, emails) into a strict, validated JSON payload by pairing the Meridian gateway with a response schema. The model is forced to emit tokens that satisfy your shape, so downstream code never has to guard against drift.

1. Define the target schema

Start with the smallest JSON Schema that captures the fields you actually need. Mark every required field explicitly and set strict: true so the gateway refuses to emit extras. Tight schemas are faster, cheaper, and easier to validate downstream.

2. Call the router with response_format

Pass the schema under response_format.json_schema. The router picks a model that supports structured output and constrains decoding to your shape. You get a single string in choices[0].message.content that always parses.

import { Meridian } from '@meridian/sdk';

const client = new Meridian({ apiKey: process.env.MERIDIAN_KEY });

const schema = {
  type: 'object',
  properties: {
    invoice_number: { type: 'string' },
    total_amount: { type: 'number' },
    line_items: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          description: { type: 'string' },
          quantity: { type: 'integer' },
          unit_price: { type: 'number' }
        },
        required: ['description', 'quantity', 'unit_price']
      }
    }
  },
  required: ['invoice_number', 'total_amount', 'line_items']
};

const result = await client.chat.completions.create({
  model: 'azure/model-router',
  messages: [
    { role: 'system', content: 'Extract invoice fields as JSON.' },
    { role: 'user', content: rawInvoiceText }
  ],
  response_format: {
    type: 'json_schema',
    json_schema: { name: 'Invoice', schema, strict: true }
  }
});

const invoice = JSON.parse(result.choices[0].message.content);

3. Validate and store

Even with strict mode, run the parsed object through a runtime validator (Zod, Ajv) before persisting. Treat the model output as untrusted input: log schema misses, retry once with a corrective system message, and only then surface an error to the caller. This keeps your pipeline self-healing.