JSON and function calling
Receive content in JSON or connect functions from your application to the HINOW models.
Updated on Aug 09, 2026
Use JSON mode when your application needs to receive an object instead of free text. Use function calling when the model needs to select an operation and supply its arguments.
- JSON mode —
response_format: {"type": "json_object"}requests a response in valid JSON. The expected fields and values are still defined in the instructions and validated by the application. - Function calling —
toolsdescribes operations and parameters in JSON Schema. The model can request a function; your application validates the arguments, runs the action and decides how to continue. This mechanism is also used by Agents.
Set response_format: {"type": "json_object"} and describe the fields, types and allowed values in system:
curl https://api.hinow.ai/v1/chat/completions \
-H "Authorization: Bearer $HINOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "hinow/higenesis",
"temperature": 0,
"messages": [
{"role": "system", "content": "Extraia o evento. Responda apenas com JSON no formato {\"nome\": string, \"dia\": string, \"participantes\": string[]}."},
{"role": "user", "content": "Alice e Bob vão à feira de ciências na sexta-feira."}
],
"response_format": {"type": "json_object"}
}'from openai import OpenAI
import os, json
client = OpenAI(base_url="https://api.hinow.ai/v1", api_key=os.environ["HINOW_API_KEY"])
resposta = client.chat.completions.create(
model="hinow/higenesis",
temperature=0,
messages=[
{
"role": "system",
"content": 'Extraia o evento. Responda apenas com JSON no formato '
'{"nome": string, "dia": string, "participantes": string[]}.',
},
{"role": "user", "content": "Alice e Bob vão à feira de ciências na sexta-feira."},
],
response_format={"type": "json_object"},
)
evento = json.loads(resposta.choices[0].message.content)import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.hinow.ai/v1',
apiKey: process.env.HINOW_API_KEY,
});
const resposta = await client.chat.completions.create({
model: 'hinow/higenesis',
temperature: 0,
messages: [
{
role: 'system',
content:
'Extraia o evento. Responda apenas com JSON no formato ' +
'{"nome": string, "dia": string, "participantes": string[]}.',
},
{ role: 'user', content: 'Alice e Bob vão à feira de ciências na sexta-feira.' },
],
response_format: { type: 'json_object' },
});
const evento = JSON.parse(resposta.choices[0].message.content);The response to this call, exactly as the API returned it:
{
"nome": "feira de ciências",
"dia": "sexta-feira",
"participantes": ["Alice", "Bob"]
}JSON mode avoids a free-text response, but it does not automatically enforce the schema described in the prompt. Parse it, validate the fields and handle incomplete responses, out-of-domain values and generations interrupted by a limit.
Declare each operation in tools, with a name, a description and parameters in JSON Schema. When the model decides to use a tool, the response will include tool_calls:
curl https://api.hinow.ai/v1/chat/completions \
-H "Authorization: Bearer $HINOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "hinow/higenesis",
"temperature": 0,
"messages": [
{"role": "user", "content": "Registre o evento: Alice e Bob vão à feira de ciências na sexta-feira."}
],
"tools": [{
"type": "function",
"function": {
"name": "registrar_evento",
"description": "Registra um evento extraído do texto",
"parameters": {
"type": "object",
"properties": {
"nome": {"type": "string"},
"dia": {"type": "string"},
"participantes": {"type": "array", "items": {"type": "string"}}
},
"required": ["nome", "dia", "participantes"]
}
}
}],
"tool_choice": "auto"
}'from openai import OpenAI
import os, json
client = OpenAI(base_url="https://api.hinow.ai/v1", api_key=os.environ["HINOW_API_KEY"])
resposta = client.chat.completions.create(
model="hinow/higenesis",
temperature=0,
messages=[
{"role": "user", "content": "Registre o evento: Alice e Bob vão à feira de ciências na sexta-feira."},
],
tools=[{
"type": "function",
"function": {
"name": "registrar_evento",
"description": "Registra um evento extraído do texto",
"parameters": {
"type": "object",
"properties": {
"nome": {"type": "string"},
"dia": {"type": "string"},
"participantes": {"type": "array", "items": {"type": "string"}},
},
"required": ["nome", "dia", "participantes"],
},
},
}],
tool_choice="auto",
)
chamada = resposta.choices[0].message.tool_calls[0]
argumentos = json.loads(chamada.function.arguments)import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.hinow.ai/v1',
apiKey: process.env.HINOW_API_KEY,
});
const resposta = await client.chat.completions.create({
model: 'hinow/higenesis',
temperature: 0,
messages: [
{ role: 'user', content: 'Registre o evento: Alice e Bob vão à feira de ciências na sexta-feira.' },
],
tools: [{
type: 'function',
function: {
name: 'registrar_evento',
description: 'Registra um evento extraído do texto',
parameters: {
type: 'object',
properties: {
nome: { type: 'string' },
dia: { type: 'string' },
participantes: { type: 'array', items: { type: 'string' } },
},
required: ['nome', 'dia', 'participantes'],
},
},
}],
tool_choice: 'auto',
});
const chamada = resposta.choices[0].message.tool_calls[0];
const argumentos = JSON.parse(chamada.function.arguments);The response comes with finish_reason: "tool_calls" and the call assembled:
{
"choices": [
{
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_00_tYbEz310...",
"type": "function",
"function": {
"name": "registrar_evento",
"arguments": "{\"nome\": \"Feira de Ciências\", \"dia\": \"sexta-feira\", \"participantes\": [\"Alice\", \"Bob\"]}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}arguments is a string
The arguments arrive as a JSON string. Parse them and validate the result against the schema before running the function. Never use model-generated arguments as authorization for a sensitive action.
The declaration tells the model which operations exist; it does not run code. Your application receives the request, validates permissions and arguments, runs the function and returns the result when the workflow requires it. For ready-made orchestration, see Agents.
| JSON mode | Function calling | |
|---|---|---|
| Where the schema lives | In system, as text | In tools, as JSON Schema |
| What the API delivers | Content in JSON | Function name and arguments in JSON |
| Validation | Required in the application | Required before running |
| Multiple formats in the same call | No — one format per prompt | Yes — one tool per format |
| When to use it | Simple extraction and classification | Actions, multiple formats, agents |
In this example, the application expects a closed category, a numeric urgency and a short summary:
Você classifica chamados de suporte.
Responda apenas com JSON no formato:
{"categoria": string, "urgencia": number, "resumo": string}
categoria: uma de "cobranca", "tecnico", "conta".
urgencia: inteiro de 1 a 5.
resumo: no máximo 15 palavras.// user: "meu cartão foi cobrado duas vezes esse mês e ninguém me responde faz 3 dias"
{
"categoria": "cobranca",
"urgencia": 5,
"resumo": "Cobrança duplicada no cartão, sem resposta há 3 dias."
}Allowed values reduce label variation and make validation objective. Even so, reject any category outside the list before storing or routing the ticket.
When a decision needs to be reviewed, ask for a short justification and the evidence used. That is more useful for auditing than asking for a long transcript of the internal reasoning.
Classifique o pedido e informe a decisão.
Responda apenas com JSON no formato:
{"decisao": string, "justificativa": string, "evidencias": string[]}
A justificativa deve ter no máximo duas frases. Em evidencias,
inclua somente trechos presentes na entrada.Treat the model's response as external input. A robust workflow has three steps:
- Parse it with
json.loadsorJSON.parseand handle failures. - Validate it against a schema with Zod, Pydantic or the validator used by the project. Reject missing fields, incorrect types and values outside the enum.
- Validate the business rule — the schema accepts
urgencia: 5; if your workflow only escalates to on-call from 4 upward, that decision belongs in the code.
When validation fails, log the reason and apply an explicit policy: retry with the validation error, use a more capable model, request human review or end the workflow.
Partial JSON cannot be validated as a complete document. If you use stream: true, accumulate the delta chunks and parse only after the final event. In backend pipelines, receiving the whole response usually simplifies validation, retries and error handling.
- Use a low temperature when the task has an expected answer and little room for variation.
- Enumerate the possible values of every category field.
- Names that say what the field is — the model reads the names;
resumo_uma_linhaguides more thantexto2. - Define the no-answer case — "when a field cannot be determined, use
null" avoids invented values. - One format per call in JSON mode; if the same route needs different formats, use function calling with one tool per format.

