Tara API
A simple HTTP API for Tara — Tratok's privacy-first AI assistant. Bearer-authenticated, JSON in / JSON out. Approved developers can integrate Tara into their own apps and services.
v1 JSON Bearer auth Free
Two endpoints, one key
Tara exposes two HTTP endpoints under the same API key. Use whichever fits the integration:
POST /api/v1/chat.php— simple chat. String in, string out. Best for chatbots, content generation, Q&A bots.POST /api/v1/agent.php— agent / tools. Full Anthropic Messages shape with multi-block content, tool calling, and tool results. Best for agent loops, function-calling apps, and integrations that need Tara to interact with your own APIs.
Same Bearer key works on both. Same rate limits. The differences are the request & response shapes.
Quick start
1. Apply for access. Approval usually takes a couple of business days.
2. Once approved, sign in to your account dashboard and create an API key.
3. Call the endpoint:
curl https://tara.tratok.com/api/v1/chat.php \
-H "Authorization: Bearer tara_sk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{ "role": "user", "content": "Hello, Tara." }
]
}'
Response:
{
"id": "tara_20260518_a1b2c3d4e5f60718",
"content": "Hello! How can I help you today?",
"finish_reason": "end_turn",
"usage": {
"prompt_tokens": 42,
"completion_tokens": 9,
"total_tokens": 51
},
"created": 1779302400,
"latency_ms": 1387
}
Endpoints
POST /api/v1/chat.php
Send a chat conversation and receive Tara's reply.
Request headers
Authorization: Bearer <your-key>— requiredContent-Type: application/json— required
Request body
{
"messages": [
{ "role": "user", "content": "Plan a weekend in Dubai" },
{ "role": "assistant", "content": "Sure! Here are a few options…" },
{ "role": "user", "content": "Make it budget-friendly" }
],
"max_tokens": 1500,
"temperature": 0.75,
"top_p": 0.95
}
messages(required) — array of{role, content}objects.rolemust be"user"or"assistant". The last message MUST be a user message. Keep history to ~60 turns or fewer (older turns are truncated). Each message capped at 16,000 characters.max_tokens— integer, 1–4000, default1500.temperature— float, 0.0–1.5, default0.75.top_p— float, 0.0–1.0, default0.95.
Response body (success — HTTP 200)
{
"id": "tara_…",
"content": "…assistant reply…",
"finish_reason": "end_turn" | "max_tokens" | "stop_sequence",
"usage": {
"prompt_tokens": N,
"completion_tokens": M,
"total_tokens": N + M
},
"created": 1779302400,
"latency_ms": 1387
}
Error responses
All errors return a JSON body with error (machine code) and message (human text).
HTTP 400 bad_request— malformed JSON, missingmessages, last message wasn't from user, etc.HTTP 401 unauthorized— missing, malformed, revoked, or unapproved API key.HTTP 413 payload_too_large— request body over 128 KB.HTTP 429 rate_limited— per-minute, per-day, or token cap exceeded. Response includesretry_afterseconds.HTTP 502 upstream_error— temporary upstream issue. Safe to retry after a short backoff.
Agent API — /api/v1/agent.php
Same auth and rate limits as /chat, but a richer request and response shape based on Anthropic's Messages API. Use this when you want Tara to:
- Call your own tools / functions — define them in
tools[], Tara decides when to use them and emitstool_useblocks for your code to execute. - Work with structured content blocks — each message's
contentcan be a string OR an array of{type: "text" | "tool_use" | "tool_result"}blocks. - Run multi-turn agent loops — pass back
tool_resultblocks to continue the conversation.
Request body
{
"messages": [
{ "role": "user", "content": "What's the weather in Dubai?" }
],
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "City name" }
},
"required": ["location"]
}
}
],
"tool_choice": { "type": "auto" },
"max_tokens": 1500,
"temperature": 0.75,
"system": "Optional caller-supplied additional context."
}
Request fields
messages(required) — array of{role, content}. Content can be a plain string OR an array of content blocks (see below). Max 60 turns, 16 KB per text block, 256 KB total request body.tools— array of tool definitions. Max 20 per request. Each tool needsname(matching[a-zA-Z_][a-zA-Z0-9_]{0,63}),description(≤ 1024 chars), andinput_schema(a JSON Schema object).tool_choice—"auto"(default),"any"(must call a tool),"none"(no tools this turn), or{"type":"tool","name":"my_tool"}to force a specific tool.max_tokens— 1–4000, default 1500.temperature— 0.0–1.5, default 0.75.top_p— 0.0–1.0, default 0.95.system— optional. Caller-supplied context appended to Tara's built-in system prompt (Tara's identity rules take precedence). Capped at 4000 chars.
Content block types
When a message's content is an array, each block is one of:
// Plain text
{ "type": "text", "text": "..." }
// Assistant invoking one of your tools
{ "type": "tool_use", "id": "toolu_01...", "name": "get_weather",
"input": { "location": "Dubai" } }
// You returning a tool result
{ "type": "tool_result", "tool_use_id": "toolu_01...",
"content": "Sunny, 32°C" }
Response body
{
"id": "tara_msg_20260518_a1b2c3d4e5f60718",
"role": "assistant",
"content": [
{ "type": "text", "text": "I'll check the weather." },
{ "type": "tool_use", "id": "toolu_01a2b3c4d5e6",
"name": "get_weather", "input": { "location": "Dubai" } }
],
"stop_reason": "tool_use",
"usage": { "input_tokens": 142, "output_tokens": 38, "total_tokens": 180 },
"tool_calls": 1,
"created": 1779302400,
"latency_ms": 1387
}
stop_reason values
end_turn— Tara is done; final text answer is incontent[].tool_use— Tara wants you to run one or more tools and call back.max_tokens— token cap hit mid-response; consider raisingmax_tokens.
Full agent loop example (Python)
import os, json, requests
def get_weather(location):
return f"Sunny, 32°C in {location}"
TOOLS = [{
"name": "get_weather",
"description": "Get the current weather for a given location",
"input_schema": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
},
}]
messages = [{"role": "user", "content": "What's the weather in Dubai?"}]
while True:
r = requests.post(
"https://tara.tratok.com/api/v1/agent.php",
headers={
"Authorization": f"Bearer {os.environ['TARA_API_KEY']}",
"Content-Type": "application/json",
},
json={"messages": messages, "tools": TOOLS},
timeout=120,
).json()
# Add assistant's response (entire content array) to history
messages.append({"role": "assistant", "content": r["content"]})
if r["stop_reason"] != "tool_use":
# Final answer — pull any text blocks out
text = "".join(b["text"] for b in r["content"] if b["type"] == "text")
print(text)
break
# Run each tool the model asked for, send the results back
tool_results = []
for block in r["content"]:
if block["type"] == "tool_use":
if block["name"] == "get_weather":
result = get_weather(block["input"]["location"])
tool_results.append({
"type": "tool_result",
"tool_use_id": block["id"],
"content": result,
})
messages.append({"role": "user", "content": tool_results})
Rate limits & quotas
Per-account defaults at launch (we can raise them on request):
- 60 requests / minute
- 1,000 requests / day
- 100,000 tokens / day (input + output)
Exceeding any of these returns HTTP 429 with a retry_after hint. Your live counters are visible on the account dashboard.
Example clients
JavaScript (fetch)
const res = await fetch('https://tara.tratok.com/api/v1/chat.php', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.TARA_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
messages: [{ role: 'user', content: 'Hello!' }],
}),
});
const data = await res.json();
console.log(data.content);
Python (requests)
import os, requests
r = requests.post(
'https://tara.tratok.com/api/v1/chat.php',
headers={
'Authorization': f"Bearer {os.environ['TARA_API_KEY']}",
'Content-Type': 'application/json',
},
json={'messages': [{'role': 'user', 'content': 'Hello!'}]},
timeout=120,
)
r.raise_for_status()
print(r.json()['content'])
PHP (cURL)
$ch = curl_init('https://tara.tratok.com/api/v1/chat.php');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TARA_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'messages' => [['role' => 'user', 'content' => 'Hello!']],
]),
]);
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $resp['content'];
Support
Questions, quota increases, or bug reports: open a ticket at support.tratok.net.
