const response = await fetch(`${BASE_URL}/v1/chat/completions`, {
method: 'POST',
headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'gemini-2.5-flash',
messages: [{ role: 'user', content: 'Explain quantum mechanics.' }],
stream: true,
}),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
// A network chunk can split an SSE frame mid-line, so accumulate and only
// parse complete lines — keep the trailing partial line for the next read.
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop() ?? '';
for (const line of lines) {
if (!line.startsWith('data: ')) continue;
const payload = line.slice(6);
if (payload === '[DONE]') break;
const chunk = JSON.parse(payload);
if (chunk.error) throw new Error(chunk.error.message); // mid-stream failure
const text = chunk.choices[0]?.delta?.content ?? '';
process.stdout.write(text); // or update your UI
}
}
A stream can fail after it starts
Once the response is 200, a failure arrives as data: {"error":{...}} — not a status code —
or the connection just drops with no [DONE]. There is no resumption; retry the whole request,
and note that tokens already streamed are billed. See Error Handling.
Tool calling (function calling)
What is tool calling?
On its own the 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", "search the docs" — and then use what
comes back to write its answer. You define the tools, your app runs them, and Tarqa only relays
the request and the result. Nothing runs on Tarqa's side.
Pass tools to let the model request a call into your own application — for example,
to answer a question by querying your own database. Tarqa never executes the tool or
sees anything beyond the arguments and the result you send back; execution always
happens in your own app.
You can try this without writing any code in the Playground: open the Tools panel, paste
a tool definition, and paste the result back when the model asks for it.
Request with tools
{
"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"]
}
}
}
]
}
The model then replies normally with finish_reason: "stop" and a text answer. When
streaming, tool-call arguments arrive as one complete SSE frame (not token-by-token)
with finish_reason: "tool_calls" on the delta.tool_calls chunk.
The JS and Python SDKs include a runTools / run_tools helper that drives this whole
round trip for you — see sdk/javascript/ and sdk/python/ in the repo, and
docs/api/agent-integration-sdk.md for the full function-calling reference.
Features
Real-time streaming · tool/function calling · automatic usage tracking and analytics · switch models without changing code · conversation history support