Define Functions with JSON Schema
On this page
The contract between your code and the model
For the Mistral model to call your functions, it needs to know what exists and how to use it. This is the role of JSON Schema: a standardized format that describes each function—its name, what it does, what parameters it expects, and which ones are mandatory.
Keep one thing in mind throughout this lesson: the model never sees your Python code. It only sees this specification. If your function handles lowercase IDs gracefully but the schema doesn’t say so, the model ignores that capability. The more precise and well-documented your schema is, the more accurate the generated arguments will be.
Anatomy of a tool specification
Every tool sent to the Mistral API follows the same structure:
tool = {
"type": "function",
"function": {
"name": "function_name",
"description": "Clear description of what the function does",
"parameters": {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Parameter description"
},
"param2": {
"type": "integer",
"description": "Parameter description"
}
},
"required": ["param1"]
}
}
}
| Field | Role |
|---|---|
type | Always "function" (other types may exist in the future) |
function.name | The exact name of your Python function—this is what the model returns in tool_calls |
function.description | A clear sentence that helps the model choose the right function |
function.parameters | A JSON Schema object describing the expected parameters |
required | The list of mandatory parameters |
Supported JSON Schema types
The type vocabulary available for describing parameters is intentionally restricted, and each type guides the model differently. An enum, in particular, does more than document: it shuts the door on invented values.
# String — free text or constrained
{"type": "string", "description": "Transaction ID"}
# String with enum — limited values
{"type": "string", "enum": ["asc", "desc"], "description": "Sort order"}
# Integer — whole number
{"type": "integer", "description": "Number of results to return"}
# Number — decimal number
{"type": "number", "description": "Amount in euros"}
# Boolean — true/false
{"type": "boolean", "description": "Include canceled transactions"}
# Array — list of values
{
"type": "array",
"items": {"type": "string"},
"description": "List of transaction IDs"
}
# Object — nested object
{
"type": "object",
"properties": {
"city": {"type": "string"},
"country": {"type": "string"}
},
"description": "Shipping address"
}
Distinguish clearly between integer and number: an amount in euros like 125.50 requires a number, while a count of results to return is an integer. Declaring an amount as an integer will cause the model to round it.
Complete example: two complementary functions
Here is a realistic example with two payment-related functions, inspired by the official Mistral documentation:
tools = [
{
"type": "function",
"function": {
"name": "retrieve_payment_status",
"description": "Retrieves the status of a payment (paid, pending, failed) "
"based on the transaction ID.",
"parameters": {
"type": "object",
"properties": {
"transaction_id": {
"type": "string",
"description": "The unique transaction ID (e.g., T1001)"
}
},
"required": ["transaction_id"]
}
}
},
{
"type": "function",
"function": {
"name": "retrieve_payment_date",
"description": "Retrieves the date when a payment was made "
"based on the transaction ID.",
"parameters": {
"type": "object",
"properties": {
"transaction_id": {
"type": "string",
"description": "The unique transaction ID (e.g., T1001)"
}
},
"required": ["transaction_id"]
}
}
}
]
Both functions expect exactly the same parameter, transaction_id, yet the model must choose between them. This choice relies entirely on the function description. “Has this payment gone through?” maps to retrieve_payment_status; “When was it?” maps to retrieve_payment_date. If you had written two vague, interchangeable descriptions, the model would get it wrong half the time—and you would blame the model when the fault lies in the schema.
Required vs. optional parameters
The distinction between required and optional parameters determines what the model is allowed to omit.
{
"type": "function",
"function": {
"name": "search_transactions",
"description": "Searches for transactions based on various criteria",
"parameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["paid", "pending", "failed"],
"description": "Filter by payment status"
},
"date_from": {
"type": "string",
"description": "Start date in YYYY-MM-DD format"
},
"date_to": {
"type": "string",
"description": "End date in YYYY-MM-DD format"
},
"min_amount": {
"type": "number",
"description": "Minimum amount in euros"
}
},
"required": ["status"]
}
}
}
Here, only status is required; the other parameters are included only if the user mentions them. Compare two formulations. For “Show me failed payments,” the model generates simply {"status": "failed"}. For “Show me failed payments from March 2026,” it adds date_from and date_to on its own. Making those dates required would have broken the first query, or worse, pushed the model to invent a date range.
Best practices for descriptions
Description quality directly impacts model accuracy. The counter-examples below are more instructive than any abstract rule.
# Bad — too vague
{"description": "Retrieves data"}
# Good — precise and contextual
{"description": "Retrieves the status of a payment (paid, pending, failed) "
"based on the unique transaction ID"}
# Bad — no description for the parameter
{"transaction_id": {"type": "string"}}
# Good — description with example
{"transaction_id": {
"type": "string",
"description": "Unique transaction ID (format: T followed by 4 digits, e.g., T1001)"
}}
A good description states in one sentence what the function does, specifies the expected format for each parameter, and provides an example whenever that format isn’t obvious—T1001 is better than “transaction ID.” When possible values are limited, don’t describe them in prose: declare them with enum. That is the only way to make them binding.
Key takeaways
- JSON Schema is the contract between your code and the model—it describes your functions without exposing the code
- Every tool has a
name, adescription, and typedparameters - Supported types include
string,integer,number,boolean,array, andobject - The
requiredlist distinguishes mandatory parameters from optional ones - Precise descriptions with examples significantly improve model accuracy