Skip to main content
NeosantaraAI models are capable of interacting with tools (also known as functions), allowing you to extend the AI’s capabilities to perform a wider variety of tasks, such as fetching real-time data, performing calculations, or interacting with external systems. Here’s an example of how to provide tools to NeosantaraAI using the chat completions API:
curl https://api.neosantara.xyz/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $NEOSANTARA_API_KEY" \
  -d '{
    "model": "nusantara-base",
    "max_tokens": 1024,
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather in a given location",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. Jakarta, ID"
              }
            },
            "required": ["location"]
          }
        }
      }
    ],
    "messages": [
      {
        "role": "user",
        "content": "What is the weather like in Jakarta?"
      }
    ]
  }'

How Tool Use Works

NeosantaraAI’s tool use functionality follows a common pattern, similar to OpenAI’s function calling, where you provide the model with descriptions of available tools, and the model decides if and how to use them. Integrate client-side tools with NeosantaraAI in these steps:
1

Provide NeosantaraAI with tools and a user prompt

  • Define tools with names, descriptions, and input schemas (parameters) in your API request within the tools parameter.
  • Include a user prompt that might require these tools, e.g., “What’s the weather in Jakarta?”
2

NeosantaraAI decides to use a tool

  • The model assesses if any tools can help with the user’s query.
  • If yes, the model constructs a tool_calls object within its response, containing the name of the tool to be called and the arguments (input) for that tool.
  • The API response will have a finish_reason of tool_calls.
3

Execute the tool and return results

  • Your application extracts the tool name and input from NeosantaraAI’s tool_calls response.
  • Your application then executes the actual tool code on your system.
  • Return the results to the model in a new user message with a tool role, containing the tool_call_id and the content of the tool’s output.
4

NeosantaraAI uses tool result to formulate a response

  • NeosantaraAI analyzes the tool results you provide to craft its final, natural language response to the original user prompt.
Note: Steps 3 and 4 are optional. For some workflows, NeosantaraAI’s tool use request (step 2) might be all you need, without sending results back to the model.

Tool Use Examples

Here are a few code examples demonstrating various tool use patterns and techniques. The examples use simple tools for clarity.
curl https://api.neosantara.xyz/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $NEOSANTARA_API_KEY" \
  --data '{
    "model": "nusantara-base",
    "max_tokens": 1024,
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. Jakarta, ID"
            },
            "unit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "description": "The unit of temperature, either \"celsius\" or \"fahrenheit\""
            }
          },
          "required": ["location"]
        }
      }
    }],
    "messages": [{"role": "user", "content": "What is the weather like in Jakarta?"}]
  }'
NeosantaraAI will return a response similar to:
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1701234567,
  "model": "nusantara-base",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_...",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"location\": \"Jakarta, ID\", \"unit\": \"celsius\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 50,
    "completion_tokens": 10,
    "total_tokens": 60
  },
  "_metadata": {
    "creator": "neosantara.xyz",
    "status": true,
    "tier": "Free"
    // ...
  }
}
You would then need to execute the get_weather function with the provided input, and return the result in a new user message:
curl https://api.neosantara.xyz/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $NEOSANTARA_API_KEY" \
  --data '{
    "model": "nusantara-base",
    "max_tokens": 1024,
    "tools": [
        {
          "type": "function",
          "function": {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
              "type": "object",
              "properties": {
                "location": {
                  "type": "string",
                  "description": "The city and state, e.g. Jakarta, ID"
                },
                "unit": {
                  "type": "string",
                  "enum": ["celsius", "fahrenheit"],
                  "description": "The unit of temperature, either \"celsius\" or \"fahrenheit\""
                }
              },
              "required": ["location"]
            }
          }
        }
    ],
    "messages": [
        {
            "role": "user",
            "content": "What is the weather like in Jakarta?"
        },
        {
            "role": "assistant",
            "content": null,
            "tool_calls": [
                {
                    "id": "call_toolu_01A09q90qw90lq917835lq9",
                    "type": "function",
                    "function": {
                        "name": "get_weather",
                        "arguments": "{\"location\": \"Jakarta, ID\", \"unit\": \"celsius\"}"
                    }
                }
            ]
        },
        {
            "role": "tool",
            "tool_call_id": "call_toolu_01A09q90qw90lq917835lq9",
            "content": "{\"temperature\": 28, \"unit\": \"celsius\", \"description\": \"Partly cloudy\"}"
        }
    ]
  }'
This will print NeosantaraAI’s final response, incorporating the weather data:
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1701234567,
  "model": "nusantara-base",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The weather in Jakarta is currently 28 degrees Celsius, partly cloudy."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 70,
    "completion_tokens": 20,
    "total_tokens": 90
  },
  "_metadata": {
    "creator": "neosantara.xyz",
    "status": true,
    "tier": "Free"
    // ...
  }
}
NeosantaraAI can call multiple tools in parallel within a single response, which is useful for tasks that require multiple independent operations. When using parallel tools, all tool_calls blocks are included in a single assistant message, and all corresponding tool results must be provided in the subsequent user message, each with its tool_call_id.
curl https://api.neosantara.xyz/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $NEOSANTARA_API_KEY" \
  --data '{
    "model": "nusantara-base",
    "max_tokens": 1024,
    "tools": [{
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather in a given location",
          "parameters": {
            "type": "object",
            "properties": {
              "location": { "type": "string", "description": "The city and state, e.g. Jakarta, ID" }
            },
            "required": ["location"]
          }
        }
      },
      {
        "type": "function",
        "function": {
          "name": "get_time",
          "description": "Get the current time in a given time zone",
          "parameters": {
            "type": "object",
            "properties": {
              "timezone": { "type": "string", "description": "The IANA time zone name, e.g. Asia/Jakarta" }
            },
            "required": ["timezone"]
          }
        }
      }
    ],
    "messages": [{"role": "user", "content": "What is the weather like right now in Jakarta? Also what time is it there?"}]
  }'
If the user’s prompt doesn’t include enough information to fill all the required parameters for a tool, NeosantaraAI is designed to recognize that a parameter is missing and ask for it.For example, using the get_weather tool, if you ask “What’s the weather?” without specifying a location, the model is likely to respond with a clarifying question instead of making a tool call.
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1701234567,
  "model": "nusantara-base",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Sure, I can tell you the weather. What city and state (or country) are you interested in?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 40,
    "completion_tokens": 20,
    "total_tokens": 60
  },
  "_metadata": {
    "creator": "neosantara.xyz",
    "status": true,
    "tier": "Free"
    // ...
  }
}
Some tasks may require calling multiple tools in sequence, using the output of one tool as the input to another. In such a case, NeosantaraAI will call one tool at a time.Here’s an example of using a get_location_from_ip tool to get the user’s location based on their IP, then passing that location to the get_weather tool:
curl https://api.neosantara.xyz/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $NEOSANTARA_API_KEY" \
  --data '{
    "model": "nusantara-base",
    "max_tokens": 1024,
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_location_from_ip",
          "description": "Get the current user location based on their IP address. This tool has no parameters or arguments.",
          "parameters": {
            "type": "object",
            "properties": {}
          }
        }
      },
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather in a given location",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. Jakarta, ID"
              },
              "unit": {
                "type": "string",
                "enum": ["celsius", "fahrenheit"],
                "description": "The unit of temperature, either \"celsius\" or \"fahrenheit\""
              }
            },
            "required": ["location"]
          }
        }
      }
    ],
    "messages": [{"role": "user", "content": "What is the weather like where I am?"}]
  }'
The full conversation flow would involve multiple API calls:
  1. User asks: “What’s the weather like where I am?”
  2. AI responds (Tool Call 1): Calls get_location_from_ip.
  3. Your code executes tool: Gets location (e.g., “Bandung, West Java”).
  4. Your code sends result to AI: Sends tool message with location.
  5. AI responds (Tool Call 2): Calls get_weather with “Bandung, West Java”.
  6. Your code executes tool: Gets weather data (e.g., “25°C, Sunny”).
  7. Your code sends result to AI: Sends tool message with weather.
  8. AI responds (Final Answer): “The weather in Bandung, West Java is currently 25°C and sunny.”
You can use tools to instruct NeosantaraAI to produce JSON output that follows a specific schema, even if you don’t intend to execute the output through a tool or function. This is often used for structured data extraction or generation.When using tools in this way:
  • You typically provide a single tool.
  • You should set tool_choice to {"type": "function", "function": {"name": "your_tool_name"}} to explicitly instruct the model to use that tool.
  • The function’s parameters define the exact JSON schema the model should adhere to.
The following uses a record_summary tool to describe an image following a particular JSON format. Note that this requires a model with vision capabilities (e.g., vision-emas-2045).
#!/bin/bash
IMAGE_URL="[https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg](https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg)"
IMAGE_MEDIA_TYPE="image/jpeg"
IMAGE_BASE64=$(curl "$IMAGE_URL" | base64)

curl https://api.neosantara.xyz/v1/chat/completions \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer $NEOSANTARA_API_KEY" \
  --data '{
    "model": "vision-emas-2045",
    "max_tokens": 1024,
    "tools": [{
      "type": "function",
      "function": {
        "name": "record_summary",
        "description": "Record summary of an image using well-structured JSON.",
        "parameters": {
          "type": "object",
          "properties": {
            "key_colors": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "r": { "type": "number", "description": "red value [0.0, 1.0]" },
                  "g": { "type": "number", "description": "green value [0.0, 1.0]" },
                  "b": { "type": "number", "description": "blue value [0.0, 1.0]" },
                  "name": { "type": "string", "description": "Human-readable color name in snake_case, e.g. \"olive_green\" or \"turquoise\"" }
                },
                "required": [ "r", "g", "b", "name" ]
              },
              "description": "Key colors in the image. Limit to less than four."
            },
            "description": {
              "type": "string",
              "description": "Image description. One to two sentences max."
            },
            "estimated_year": {
              "type": "integer",
              "description": "Estimated year that the image was taken, if it is a photo. Only set this if the image appears to be non-fictional. Rough estimates are okay!"
            }
          },
          "required": [ "key_colors", "description" ]
        }
      }
    }],
    "tool_choice": {"type": "function", "function": {"name": "record_summary"}},
    "messages": [
        {"role": "user", "content": [
            {"type": "image_url", "image_url": {"url": "'$IMAGE_URL'"}},
            {"type": "text", "text": "Describe this image in JSON format using the provided tool schema."}
        ]}
    ]
  }'
NeosantaraAI will return a response containing the structured JSON output within a tool_calls block:
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1701234567,
  "model": "vision-emas-2045",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_...",
            "type": "function",
            "function": {
              "name": "record_summary",
              "arguments": "{\"key_colors\": [{\"r\": 0.2, \"g\": 0.2, \"b\": 0.1, \"name\": \"dark_brown\"}, {\"r\": 0.8, \"g\": 0.7, \"b\": 0.5, \"name\": \"light_beige\"}], \"description\": \"A close-up shot of a camponotus flavomarginatus ant on a light-colored surface.\", \"estimated_year\": 2008}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 1500,
    "completion_tokens": 100,
    "total_tokens": 1600
  },
  "_metadata": {
    "creator": "neosantara.xyz",
    "status": true,
    "tier": "Free"
    // ...
  }
}

Pricing

Tool use requests are priced based on:
  1. The total number of input tokens sent to the model (including the tokens from tool definitions in the tools parameter and tool call/result messages).
  2. The number of output tokens generated (including tool calls generated by the model).
  3. Additional charges may apply for specific capabilities (e.g., vision processing for image inputs).
The additional tokens from tool use come from:
  • The tools array in API requests (tool names, descriptions, and parameter schemas).
  • tool_calls generated by the model in assistant messages.
  • tool messages (containing tool_call_id and content) sent by your application.
These token counts are added to your normal input and output tokens to calculate the total cost of a request. Refer to our pricing documentation for current per-model prices and usage tiers. When you send a tool use prompt, just like any other API request, the response will output both input and output token counts as part of the reported usage metrics.

Next Steps

Explore our other capabilities and API references: