Docs/API Reference

Chat API & Models

Stream conversational AI responses across 60+ models with one request format.

POST/v1/chat/completions
One request format for every model. To switch models, change the model field. Nothing else changes.

Send a message

curl -X POST "https://api.tarqaai.com/api/v1/chat/completions" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-2.5-flash",
    "messages": [
      { "role": "system", "content": "You are a helpful assistant." },
      { "role": "user", "content": "Explain quantum mechanics." }
    ],
    "stream": false
  }'

The response is a standard chat completion:

200 OK
{
  "id": "chatcmpl-abc123xyz",
  "object": "chat.completion",
  "created": 1751760000,
  "model": "gemini-2.5-flash",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Quantum mechanics is a branch of physics..." },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 28, "completion_tokens": 142, "total_tokens": 170 }
}
Retry safely

For non-streaming requests, send an Idempotency-Key header. A retry then returns the original response instead of running twice. See Error Handling.

Models

There are 60+ models. Always read exact IDs from GET /v1/models or the Models page in your dashboard, because the list changes. Popular ones:

ProviderModel IDs
Anthropic (Claude)claude-opus-4-6 · claude-sonnet-4-5 · claude-haiku-4-5
OpenAIgpt-4.1 · gpt-4o · o3 · o4-mini · gpt-4o-mini
Googlegemini-2.5-pro · gemini-2.5-flash · gemini-2.0-flash
Metallama-4-maverick · llama-4-scout · llama-3.3-70b
DeepSeekdeepseek-r1 · deepseek-v3
Mistralmistral-large-2 · mistral-nemo
Othersqwen3-235b · amazon-nova-pro
Your own GPUhosted-<id>

Streaming

Set "stream": true to get the reply word by word as Server-Sent Events. Each event carries a small piece of text, and the stream ends with [DONE].

What the stream looks like
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Quantum"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" mechanics"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
const stream = await client.chat.completions.create({
  model: 'gemini-2.5-flash',
  messages: [{ role: 'user', content: 'Explain quantum mechanics.' }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}
A stream can fail after it starts

Once you've received 200, an error arrives as data: {"error":{...}} instead of a status code, or the connection simply drops without [DONE]. Streams can't be resumed: retry the whole request. Tokens already streamed are billed. See Error Handling.

Tool calling

On its own, a model can't reach your database, your APIs or the internet. Tool calling lets it ask your app to run something ("look up order 42") and then use the result in its answer.

Two ways to give the model tools

Custom functions (this section): you run the tool and send back the result. Use this to build function calling into your own app.
MCP Connectors: Tarqa runs the tool for you automatically, in every chat. Use this when you just want the model to have working tools.

With custom functions, Tarqa only passes the request and the result along. It never runs your tool or sees anything beyond the arguments and the result you send back.

Try it in the Playground (no code)

  1. 1
    Open Functions
    In Build → Playground, click the Functions button under the message box. What you define here only lives in the current Playground session.
  2. 2
    Define a tool
    Use Form mode to fill in a name, a description (the model reads this to decide when to use it) and typed parameters. Or switch to JSON and paste a tools array in the same format as the API example below.
  3. 3
    Ask something that needs it
    For example: "How many orders did user 42 place last month?" for a query_db tool. It works the same with any model.
  4. 4
    Run it yourself and paste the result
    A "The model wants to use a tool" card appears with the arguments. Run that lookup in your own app, paste the result, and click Submit results. The model then finishes its answer.

Call it from the API

It's a three-step round trip.

  1. 1
    Send your tools with the message
    Request
    {
      "model": "claude-sonnet-4-5",
      "messages": [
        { "role": "user", "content": "How many orders did user 42 place last month?" }
      ],
      "tools": [
        {
          "type": "function",
          "function": {
            "name": "query_db",
            "description": "Run a read-only SQL query against the caller's own database",
            "parameters": {
              "type": "object",
              "properties": { "sql": { "type": "string" } },
              "required": ["sql"]
            }
          }
        }
      ]
    }
  2. 2
    The model asks for a tool call
    Response — finish_reason: tool_calls
    {
      "id": "chatcmpl-abc123xyz",
      "object": "chat.completion",
      "created": 1751760000,
      "model": "claude-sonnet-4-5",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": null,
            "tool_calls": [
              {
                "id": "call_1",
                "type": "function",
                "function": { "name": "query_db", "arguments": "{\"sql\":\"SELECT COUNT(*) FROM orders WHERE user_id=42 ...\"}" }
              }
            ]
          },
          "finish_reason": "tool_calls"
        }
      ],
      "usage": { "prompt_tokens": 42, "completion_tokens": 18, "total_tokens": 60 }
    }
  3. 3
    Run it, then send back the result

    Include the assistant's tool_calls message and a role: "tool" message with what your tool returned. The model then replies normally with finish_reason: "stop".

    Follow-up request
    {
      "model": "claude-sonnet-4-5",
      "messages": [
        { "role": "user", "content": "How many orders did user 42 place last month?" },
        {
          "role": "assistant",
          "content": null,
          "tool_calls": [
            { "id": "call_1", "type": "function", "function": { "name": "query_db", "arguments": "{\"sql\":\"...\"}" } }
          ]
        },
        { "role": "tool", "tool_call_id": "call_1", "content": "{\"count\": 7}" }
      ]
    }

When streaming, tool-call arguments arrive as one complete event (not piece by piece), with finish_reason: "tool_calls" on the delta.tool_calls chunk.

The upcoming Tarqa JS and Python SDKs (not published yet) add a runTools / run_tools helper that handles this whole round trip for you. See SDKs & Libraries.

FAQ

Do MCP connector tools need the tools parameter?
No. Connected MCP tools are available automatically, including on /v1/chat/completions, and Tarqa runs them for you. See MCP Connectors.
Does tool calling work on my own GPU models?
Yes, on hosted-<id> models, as long as the local server speaks the OpenAI-compatible format (LM Studio, vLLM). Ollama endpoints don't forward tool definitions yet. See GPU Tunnels.
Can I keep conversation history?
Yes. Send the earlier messages in the messages array, oldest first.
Is usage tracked?
Yes. Every call appears in your dashboard's Activity and Analytics with tokens and latency.