No KYC — no ID, no selfie, no documents. Pay in crypto: BTC, USDT, USDC, ETH, SOL, LTC
Language: English
Get an API key

Docs · tools and JSON

Tool calling and JSON output with open-weight models

The model can ask your code to run a function, then use the result in its answer; or it can reply with a JSON object your program reads directly. Both use the OpenAI request format, and both depend on the model you choose.

Last updated: · 4 min read

Quick answer

How does tool calling work on LLMwithCrypto?

Send your functions in tools, in the OpenAI format. When the model wants one, LLMwithCrypto returns finish_reason: "tool_calls" with the function name and JSON arguments; your code runs it and sends the result back as a tool message. For structured replies, response_format: {"type": "json_object"} asks for valid JSON. Both work on the models that support them, as documented on 23 October 2026.

Which models support tools and JSON?

Streaming works on every model; tool calling and JSON output follow what each model itself supports.

Test your own schema on the model you plan to use before you depend on it. A model that does not support tools answers in plain text instead of calling the function; a model that does not support JSON mode returns a 400 error for response_format.

What is the loop?

  1. Describe the functions

    Each tool has a name, a description the model reads to decide when to use it, and parameters as a JSON Schema.

  2. Send the conversation with tools

    The model either answers in text, or stops with finish_reason: "tool_calls" and one or more calls in message.tool_calls.

  3. Run each call

    Parse function.arguments (a JSON string), run your function, and never trust the arguments blindly: validate them like any user input.

  4. Send the results back

    Append the assistant message, then one tool message per call with its tool_call_id and the result as text. Call the API again; repeat until the model answers in text.

Python: a complete tool loop with gpt-oss-120b
import json
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://llmwithcrypto.com/api/v1",
    api_key=os.environ["LLMWITHCRYPTO_API_KEY"],
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order_status",
            "description": "Return the delivery status of an order.",
            "parameters": {
                "type": "object",
                "properties": {"order_id": {"type": "string"}},
                "required": ["order_id"],
            },
        },
    }
]


def get_order_status(order_id):
    return {"order_id": order_id, "status": "shipped", "eta": "2026-10-25"}


messages = [{"role": "user", "content": "Where is my order A-1042?"}]
while True:
    resp = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools, max_tokens=300)
    msg = resp.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_order_status(**args)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

What does a tool call look like in the response?

The assistant message has no text, a tool_calls array, and the choice ends with finish_reason: "tool_calls". The arguments come as a JSON string, not an object. The ids and counts below are illustrative.

Response asking for a function call (illustrative)
{
  "id": "chatcmpl-3c9d27e1",
  "object": "chat.completion",
  "created": 1792742400,
  "model": "gpt-oss-120b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_7f31",
            "type": "function",
            "function": {
              "name": "get_order_status",
              "arguments": "{\"order_id\": \"A-1042\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 118,
    "completion_tokens": 22,
    "total_tokens": 140
  }
}

How do I control when tools are used?

  • "tool_choice": "auto" (the default when tools is set): the model decides.
  • "tool_choice": "none": the model answers in text even though tools are listed.
  • "tool_choice": "required": the model must call at least one tool.
  • {"type": "function", "function": {"name": "get_order_status"}}: the model must call that one.

Every tool definition is sent as input on each call, so long descriptions and many tools raise the input tokens. Keep descriptions short and send only the tools a step needs.

How do I get valid JSON back?

Set response_format to {"type": "json_object"} and describe the expected keys in the system message: JSON mode guarantees that the reply parses, not that it has the keys you want. Keep temperature low for stable output and check the parsed object in your code before using it.

Node.js: a JSON reply with response_format
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://llmwithcrypto.com/api/v1',
  apiKey: process.env.LLMWITHCRYPTO_API_KEY,
});

const resp = await client.chat.completions.create({
  model: 'gpt-oss-120b',
  messages: [
    { role: 'system', content: 'Reply with a JSON object {"sentiment": "positive" | "negative" | "neutral", "reason": string}.' },
    { role: 'user', content: 'The delivery was late but support fixed it in an hour.' },
  ],
  response_format: { type: 'json_object' },
  temperature: 0.2,
  max_tokens: 150,
});
const result = JSON.parse(resp.choices[0].message.content);
console.log(result.sentiment, '-', result.reason);

Tools and JSON: common questions

Do tool calls cost extra?

No fee of their own. The tool definitions, the call and the results you send back are all tokens, billed like any other. You pay per token from your balance: input and output tokens are counted by the model’s own tokenizer and charged at that model’s price per 1M tokens. A call that ends in an error costs nothing.

Can the model call several tools at once?

Some models return more than one call in tool_calls. Run them all and send one tool message per call before the next request.

Does the API run my functions?

No. The model only says which function to call and with which arguments; your code runs it. Nothing is executed on our side, and nothing of the exchange is stored: We do not store your prompts or the model’s answers: once a response is sent, its text is gone. Each call leaves one log line with the time, the account, the model and the token counts, deleted after 30 days.

DeepSeek V4 Pro from $1.254 per 1M input tokens · no KYC

Get an API key