Skip to main content
Lesson 2 of 12 · Structured Output: JSON and Schemas

JSON Mode vs Custom Structured Outputs

Lesson 2 of 12 Updated July 29, 2026 Developer
On this page
  1. Two approaches, two philosophies
  2. JSON Mode: flexibility
  3. Custom Structured Outputs: rigor
  4. Detailed comparison
  5. Making the call in practice
  6. Key takeaways

Two approaches, two philosophies

The Mistral API offers two distinct mechanisms for generating structured outputs. They don’t compete; they serve different stages of a project’s lifecycle. Your choice depends on your use case, your tech stack, and the reliability level you need to maintain.

JSON Mode: flexibility

JSON Mode is the simplest approach. You enable a parameter in your request, and Mistral guarantees the output will be valid JSON. That’s it. The model remains free to choose the structure: keys, types, and nesting depth. You guide the desired format through your prompt, but no technical constraints bind the schema.

# JSON Mode — the model chooses the structure
response = client.chat.complete(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Analyze this text and return the result in JSON."}],
    response_format={"type": "json_object"}
)

This minimalism is its main strength: just one parameter to add, no schema to define upfront, and total flexibility when you’re exploring a problem or prototyping quickly. The downside is symmetrical. Nothing guarantees the exact structure of the JSON you receive: the model might omit a field, add another, or rename a key from one call to the next. Client-side validation therefore becomes mandatory, and that’s code you have to write and maintain yourself.

Custom Structured Outputs: rigor

Custom Structured Outputs shift this constraint to the API side. You define a precise schema—using Pydantic in Python or Zod in TypeScript—and Mistral forces the model to adhere to it exactly.

from pydantic import BaseModel

class Analyse(BaseModel):
    sentiment: str
    score: float
    keywords: list[str]

# Custom — the schema is enforced
response = client.chat.parse(
    model="mistral-large-latest",
    messages=[{"role": "user", "content": "Analyze this text."}],
    response_format=Analyse
)

The benefit is immediate: every field is present with the correct type, and you get back a parsed object ready to use—an instance of a Pydantic or Zod model—with full IDE autocompletion. This is the mode for production and critical pipelines. The trade-off comes down to one sentence: you must define a data model upfront, which makes exploration less flexible and imposes a slight initial development overhead.

Detailed comparison

CriterionJSON ModeCustom Structured Outputs
Activationresponse_format: {"type": "json_object"}response_format: MyModel (Pydantic/Zod)
API Methodclient.chat.complete()client.chat.parse()
Schema guaranteeNo — valid JSON onlyYes — exact schema enforced
Automatic parsingNo — manual json.loads()Yes — .parsed returns typed object
FlexibilityHigh — free structureLow — fixed structure
Ideal use casePrototyping, exploration, variable schemasProduction, critical pipelines, APIs
Validation requiredYes — mandatory client-sideMinimal — the schema does the work

Making the call in practice

Three signals point toward JSON Mode. First is the project stage: when you’re prototyping and the schema isn’t stable yet, locking down a data model slows you down without adding value. Second is the nature of the task: if the output structure legitimately varies based on the input, as in exploratory analysis where relevant dimensions aren’t known in advance, a fixed structure would be a straitjacket. Third is technical: in a language without Pydantic or Zod support, JSON Mode remains your only entry point.

Custom Structured Outputs take over as soon as the situation reverses. You’re in production and a failed extraction has a real cost; the output schema is known and stable; you’re working in Python or TypeScript; and you want to manipulate typed objects rather than anonymous dictionaries. Concretely, a pipeline that classifies support tickets all day long using the same four fields has no reason to stay in JSON Mode.

This aligns with the official Mistral documentation, which recommends using Custom Structured Outputs whenever possible. JSON Mode remains a good entry point, but Custom Outputs offer superior reliability and significantly reduce client-side validation code.

Key takeaways

  • JSON Mode = guaranteed valid JSON, free structure, simple to enable
  • Custom Structured Outputs = guaranteed exact schema, automatic parsing, ideal for production
  • Start with JSON Mode for prototyping, migrate to Custom for production
  • The two approaches are complementary, not mutually exclusive