Skip to content

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 moderesponse_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 callingtools describes 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.

JSON mode

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"}
  }'

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.

Function calling

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"
  }'

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.

Which route to choose

JSON modeFunction calling
Where the schema livesIn system, as textIn tools, as JSON Schema
What the API deliversContent in JSONFunction name and arguments in JSON
ValidationRequired in the applicationRequired before running
Multiple formats in the same callNo — one format per promptYes — one tool per format
When to use itSimple extraction and classificationActions, multiple formats, agents

Examples

Ticket triage

In this example, the application expects a closed category, a numeric urgency and a short summary:

system.txt
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.

Verifiable justification

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.

system.txt
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.

Validate on your side

Treat the model's response as external input. A robust workflow has three steps:

  1. Parse it with json.loads or JSON.parse and handle failures.
  2. 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.
  3. 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.

Streaming

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.

Best practices

  • 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_linha guides more than texto2.
  • 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.

Next steps

JSON and function calling · HINOW Developers