JSON Schemas and Descriptions
On this page
The Language of Tools: JSON Schema
For Grok to call your functions, it needs to know what they do and what parameters they expect. That’s the role of JSON schemas. Each tool is described by a structured object containing three essential pieces of information: a name, a description, and a parameter schema.
Anatomy of a Tool Definition
Here’s the complete structure of a tool as the Grok API expects it:
{
"type": "function",
"name": "get_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name (e.g., Paris, Lyon)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"default": "celsius"
}
},
"required": ["city"]
}
}
Let’s break down each field:
The type Field
Always "function" for custom functions. Other types exist for built-in tools (web_search, code_interpreter), but for your own functions, it’s invariably "function".
The name Field
The technical name of your function. It must be:
- Unique among all tools in the request
- Descriptive:
get_weatherrather thanfn1 - In snake_case by convention:
search_products,create_ticket - Short but explicit: the model uses this name to decide which tool to call
The description Field
This is the most important field for call quality. The model relies primarily on the description to decide when and how to use a tool. A good description:
- Explains what the function does in one sentence
- Specifies when to use it (if not obvious)
- Mentions edge cases if necessary
Compare these two descriptions:
❌ "Weather"
✅ "Get the current weather for a city. Returns temperature, humidity, and conditions."
The second gives the model enough context to know exactly when to call this function and what it will get in return.
The parameters Block
Parameters follow the JSON Schema format. Supported types include:
string— character stringsnumber/integer— numbersboolean— true/falsearray— listsobject— nested objectsenum— list of allowed values
The required array lists mandatory parameters. Others are optional — the model may choose to omit them.
Parameter Descriptions
Each parameter should have its own description. This is what allows the model to understand what value to pass:
{
"date": {
"type": "string",
"description": "Date in YYYY-MM-DD format. If omitted, uses today's date."
}
}
Without a description, the model has to guess the expected format — which leads to errors.
Advanced Parameters
Enums to Constrain Values
{
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"description": "Ticket priority level"
}
}
Enums are particularly useful: they tell the model the exact values it can use, eliminating format errors.
Default Values
{
"limit": {
"type": "integer",
"default": 10,
"description": "Maximum number of results to return"
}
}
The model understands it can omit this parameter if the default value works.
Nested Objects
{
"address": {
"type": "object",
"properties": {
"street": { "type": "string" },
"city": { "type": "string" },
"zip": { "type": "string" }
},
"required": ["city"]
}
}
Best Practices for Descriptions
The description is the only channel through which the model understands your tool — every word works there. Specificity first: “Search for products by name or category in the catalog” tells the model exactly when this tool applies, whereas “Search for products” leaves it guessing. Formats next: specifying “Date in ISO 8601 format (YYYY-MM-DD)” in a parameter description eliminates half the argument errors, because the model replicates the format you show it. Limits are part of the contract: “Maximum 50 results per call” prevents the model from promising the user completeness the tool won’t provide. And describing the return — “Returns an object with price, availability, and description” — helps the model plan ahead: it knows what it will have on hand before even calling.
Key Takeaways
- Each tool is defined by a
name, adescription, andparameters - The description is the #1 factor in call quality — invest time in it
- Names must be unique and in snake_case
- Use
enumto constrain possible values - Each parameter should have its own description with the expected format
- The
requiredarray distinguishes mandatory parameters from optional ones