> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trynito.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool Calling

> Function tools the model asks to call and your code runs.

Nito speaks the OpenAI tool-calling protocol. It passes your tool declarations to the model, returns the model's tool-call requests, and forwards the results you send back. **Nito does not run your function tools; your code does.**

## Two Tool Families

1. **Function tools.** You define them, the model requests them, you run them and return the result. This page.
2. **Hosted tools.** Run upstream with no round trip: `web_search` and `web_fetch`. See [Server-Side Tools](/api/features/server-side-tools).

## Declaring a Tool

```json wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
      "type": "object",
      "properties": {
        "city": { "type": "string", "description": "City name, e.g. Austin" }
      },
      "required": ["city"]
    }
  }
}
```

Each `function.name` must be unique in the request and `parameters` must be a JSON Schema object. The `description` is how the model decides when to call the tool.

`tool_choice`: `"auto"` (default when tools are present), `"none"`, `"required"`, or `{"type": "function", "function": {"name": "get_weather"}}`.

## The Loop

A tool call is at least two requests.

<Steps>
  <Step title="The model asks for a tool" icon="1" iconType="solid" stepNumber={1} titleSize="h3">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl https://app.trynito.ai/v1/chat/completions \
      -H "Authorization: Bearer $NITO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "moonshotai/kimi-k3",
        "messages": [
          {"role": "user", "content": "What is the weather in Austin?"}
        ],
        "tools": [
          {
            "type": "function",
            "function": {
              "name": "get_weather",
              "description": "Get the current weather for a city.",
              "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"]
              }
            }
          }
        ]
      }'
    ```

    The reply carries `tool_calls` and `finish_reason: "tool_calls"`:

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "",
            "tool_calls": [
              {
                "id": "call_abc123",
                "type": "function",
                "function": { "name": "get_weather", "arguments": "{\"city\": \"Austin\"}" }
              }
            ]
          },
          "finish_reason": "tool_calls"
        }
      ]
    }
    ```

    `arguments` is a JSON string; parse it. The `id` ties this request to the result you send back. Your code runs `get_weather("Austin")`.
  </Step>

  <Step title="You send the result back" icon="2" iconType="solid" stepNumber={2} titleSize="h3">
    Append the assistant's tool-call message and a `tool` message with the matching `tool_call_id`:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl https://app.trynito.ai/v1/chat/completions \
      -H "Authorization: Bearer $NITO_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "model": "moonshotai/kimi-k3",
        "messages": [
          {"role": "user", "content": "What is the weather in Austin?"},
          {
            "role": "assistant",
            "content": "",
            "tool_calls": [
              {"id": "call_abc123", "type": "function",
               "function": {"name": "get_weather", "arguments": "{\"city\": \"Austin\"}"}}
            ]
          },
          {
            "role": "tool",
            "tool_call_id": "call_abc123",
            "content": "{\"tempF\": 96, \"sky\": \"clear\"}"
          }
        ],
        "tools": [ ... same tools ... ]
      }'
    ```

    ```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "choices": [
        {
          "index": 0,
          "message": { "role": "assistant", "content": "It is 96 degrees and clear in Austin right now." },
          "finish_reason": "stop"
        }
      ]
    }
    ```

    A model may request several tools in one turn or more after seeing results. Append a `tool` message per `tool_call_id` and call again until `finish_reason` is `stop`.
  </Step>
</Steps>

## Streaming

With `stream: true`, tool calls arrive in fragments. The first chunk for a call carries `tool_calls` with `index`, `id`, `type: "function"`, and `function.name`; later chunks carry `function.arguments` fragments under the same `index`. Concatenate per index, then run the loop as above. See the [streaming format reference](/api/api-reference/streaming-format/server-sent-events).

## Privacy

Function tools work at Anonymous, Private, and Confidential on models that advertise `function_tools`. At [Encrypted](/api/api-reference/chat-and-text/encrypted), function tools work with `nito-encrypted-encrypt-all-fields: 1`, with tool definitions and results sent as ciphertext.

## Related

<CardGroup cols={3}>
  <Card title="Chat Completions" icon="message-captions" href="/api/features/chat-completions">
    The endpoint.
  </Card>

  <Card title="Streaming" icon="signal-stream" href="/api/features/streaming">
    Token by token.
  </Card>

  <Card title="Web Search" icon="magnifying-glass" href="/api/api-reference/server-tools/web-search">
    A hosted tool.
  </Card>

  <Card title="Privacy Levels" icon="file-lock" href="/privacy/levels">
    The four levels.
  </Card>

  <Card title="Chat Completions Endpoint" icon="message-captions" href="/api/api-reference/chat-and-text/chat-completions">
    Schema reference.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.