InterviewKata
AI engineering · Module 14 of 21 · Level 4: Build AI features

Model APIs and structured output

So far you've used AI through tools. Now you'll call models from your own code, to build AI features into a product. The API itself is simple. The skill is getting back data your program can trust, every time, which is what structured output is for.

1. The idea

If you ask a clerk to "tell me about this invoice", you get a friendly paragraph, and a different one each time. If you hand them a form with boxes (supplier, invoice number, date, total), you get exactly the fields you need, in exactly the right places, every time. Your program needs the form.

Every model API works the same way. You send a request:

You get back the content, a stop reason (finished, hit the token limit, wants a tool, refused) and usage (input and output tokens, which is your bill). Add streaming to show the answer as it's written.

Structured output is the key feature for products: you give the API a JSON Schema (the form), and the model's output is constrained to match it. All three major APIs now guarantee schema-valid JSON when you use it, so you no longer parse prose or retry broken JSON.

2. How it works

A request and a response. Your code checks the stop reason and the usage on every call, and stores only validated data.

Step through extracting an invoice from an email: first as prose, then with a schema.

3. Try it yourself

The same request in three APIs

Extract an invoice into a fixed shape. Choose an API to see the code; the structure is identical, only the names differ. All three were checked against the vendors' docs in October 2026.

Check the form

Even with structured output, your code should validate what it stores, because refusals, truncation and schema mistakes happen. Edit the model's output and see what a validator for this schema would accept.

    4. Why it matters at work

    Rules for any AI feature in a product. Agree them before you build:

    RuleWhy
    The model suggests; code or a person decides anything involving money, safety or complianceModels are probabilistic. Final decisions need deterministic checks or human sign-off.
    Everything that becomes data is validated against a schemaInvalid output is retried once, then refused, never stored. Structured output makes this rare, not impossible.
    Untrusted input (customer text, supplier PDFs) is data, never instructionsPut it inside clearly marked sections, and give the feature no tools that could leak or delete (Module 18).
    Check stop_reason on every call"Max tokens" means truncated output; "refusal" means no data. Neither should be stored as if it were a result.
    Log usage on every callCost per feature and per customer comes from these numbers (Module 19).
    Hide the vendor behind your own interfaceOne LlmProvider interface with Claude, OpenAI and Gemini adapters lets you switch by configuration, compare on your evals, and fail over in an outage.
    Set timeouts and retries with backoffAPIs have rate limits and occasional overloads; handle them like any network dependency.

    5. In the three APIs

    Checked against each vendor's documentation, October 2026. Your coding agent can write all of this for you; knowing the shape lets you review it.

    APIMain endpointStructured outputStrict tools
    ClaudeMessages API (client.messages.create)output_config.format with type: "json_schema" (generally available)strict: true on a tool definition
    OpenAIResponses API (client.responses.create)text.format with type: "json_schema" and strict: true; responses.parse with a Pydantic or Zod modelstrict: true on a function
    GeminiInteractions API (client.interactions.create)response_format with mime_type: "application/json" and a schemaFunction calling mode validated
    Schemas have limitsEach vendor supports a subset of JSON Schema. For example, Claude's structured outputs require additionalProperties: false and don't support numeric ranges or string lengths, so check those in your own validation code. Read your vendor's list before designing a schema.

    6. Remember it

    Memory hook: "Ask for a form, not a letter"When your code needs data, give the model a schema to fill in, then check the form before you file it.
    How this hook works: what “Ask for a form, not a letter” means

    What the slogan means, phrase by phrase

    “Ask for a form”
    Send a JSON Schema with structured output turned on. The model can only produce output that fits the boxes.
    “not a letter”
    Prose is for people. A program parsing prose with regular expressions breaks on the first unusual phrasing.
    Implied: check before filing
    Validate types, required fields and business rules in your code, and look at the stop reason. A refused or truncated form isn't a form.

    Why this picture fits: it turns a technical feature into an obvious habit. You'd never ask a clerk for a free-text letter and then try to extract the invoice total from it; give them the form.

    The story → the concept

    PaperworkThe API
    The blank formA JSON Schema
    "Fill in every box"required fields, additionalProperties: false
    A box for a date"format": "date", or a string you check
    The clerk declines to fill it inA refusal stop reason
    The clerk runs out of paperA max-tokens stop reason (truncated)
    Checking the form before filingYour validator and business rules

    Watch it on an example

    1. A letter: "This invoice from Acme, dated 3 October, totals £1,240.50…" Your regex expects a dollar sign and fails.
    2. A form: {"supplier": "Acme", "date": "2026-10-03", "total": 1240.5, "currency": "GBP"}. Every field in its box, every time.
    3. Your validator checks the total is positive and the currency is one you support, then stores it.

    The trap it saves you from

    "Please reply in JSON" in the prompt, then parsing whatever comes back. It works in the demo and fails in production on the 1 in 200 response with an apology or a code fence wrapped around it.

    It still works when…

    You use tools (Module 06): a tool's input schema is a form the model fills in to call it. With strict tool use, those forms are guaranteed too.

    7. Common mistakes

    API keys in client-side code or repositoriesCall model APIs from your server, with keys in a secret store. A key shipped in a web or mobile app will be found and used.
    Ignoring the stop reasonA truncated or refused answer stored as data causes bugs far from the cause.
    Trusting structured output for business rulesThe schema guarantees shape, not truth: a valid date can still be the wrong date. Validate meaning too, and evaluate (Module 17).
    Hard-coding one vendor everywhereA thin interface costs a day now and saves a painful migration later.

    8. Hands-on lab (roadmap week 15)

    1. Get keys for two vendors and store them as environment variables, never in code.
    2. Extract structured data from three real documents (invoices, labels, emails) with structured output in both APIs.
    3. Add a validator for business rules, and handle the stop reasons: refusal, max tokens.
    4. Log usage per call and compute the cost per document at each vendor's price (Module 04's calculator).
    5. Wrap both behind one interface (extract_invoice(text) -> Invoice) and switch vendors with a config value.

    9. Self-check quiz

    Your code needs the same five fields from every document. What do you use?

    Structured output constrains the model to your schema; a prompt request is only a request.

    The stop reason says the maximum token limit was reached. What does that mean?

    Truncated output is incomplete. Raise the limit or shorten the task, and retry.

    Where should calls to the model API come from?

    Anything in client code can be read. Keep keys on the server.

    Does a schema-valid response mean the data is correct?

    Validate meaning with business rules, and measure accuracy with evals.

    10. Go deeper

    ResourceTimeWhy
    Structured outputs (Claude)15 minJSON outputs, strict tools, and the supported schema subset.
    Structured Outputs (OpenAI)15 minSchemas, Pydantic and Zod helpers, and refusals.
    Structured output (Gemini)15 minThe same feature in the Gemini API.
    Anthropic Academy API course3–4 hFree, hands-on API fundamentals.