Documentation
Start calling the API in a few minutes
TunAI exposes an OpenAI-compatible API. Point any OpenAI SDK at https://api.tunai.tn/v1 with your API key.
Guide: use TunAI with the Oh-My-Pi coding agent
Install, connect your key, pick models and set defaults in about five minutes.
Quick start
Three steps to your first request
1. Create an API key
Go to the API keys page and create a key. Copy it — it's shown only once.
2. Add credits
Top up your balance on the billing page. Each request is metered by token usage and deducted from your balance.
3. Make your first request
Install the OpenAI SDK (pip install openai / npm install openai) and call the API:
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY", # your sk-tunai-... key
base_url="https://api.tunai.tn/v1",
)
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)Streaming
# Streaming (Server-Sent Events)
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Write a haiku."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)The stream ends with a data: [DONE] sentinel, exactly as OpenAI's does.
Tool calling, JSON mode and embeddings
Parameters are forwarded to the provider, so the OpenAI SDK's full surface works — tools, tool_choice, response_format, seed, and the penalty parameters.
Tool calling and JSON mode
# Tool calling / function calling
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "What's the weather in Tunis?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}],
)
print(response.choices[0].message.tool_calls)
# JSON mode
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "List 3 Tunisian cities as JSON."}],
response_format={"type": "json_object"},
)Embeddings
response = client.embeddings.create(
model="text-embedding-3-small",
input=["Tunis", "Sfax", "Sousse"],
)
print(len(response.data), "vectors x", len(response.data[0].embedding), "dims")Token usage
# Every response reports real token usage
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.usage.prompt_tokens, response.usage.completion_tokens)
# For streaming, ask for a final usage chunk explicitly
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.usage:
print("total tokens:", chunk.usage.total_tokens)Rate limits and request ids
Each key is limited to a per-minute request cap by default. You can set a lower limit, a monthly budget, an expiry, or restrict a key to specific endpoints on the API keys page.
Every response carries the current limit state:
x-ratelimit-limit-requests: 120
x-ratelimit-remaining-requests: 119
x-ratelimit-reset-requests: 60s
x-request-id: req_9e0d436bb573482f85d432f779d12304Quote the x-request-id in any support request — it maps to the exact call, including what it cost.
Use it with your tools
Any OpenAI-compatible client works by setting the base URL + your key.
Cursor → Settings → Models → enable “Override OpenAI Base URL”, paste the base URL and your key, then add a model id from /v1/models.
Base URL: https://api.tunai.tn/v1
API Key: YOUR_API_KEY # your sk-tunai-... key
Model: gpt-4o-mini # any id from GET https://api.tunai.tn/v1/modelsAPI reference
Authenticate with Authorization: Bearer YOUR_API_KEY
Chat completions
Create a chat completion with any supported model. Supports stream, stream_options, temperature, max_tokens, top_p, stop, tools, tool_choice, response_format, seed, presence_penalty and frequency_penalty.
Embeddings
Accepts a string or an array of strings, plus optional dimensions.
List and retrieve models
GET https://api.tunai.tn/v1/models/{model}
Public — no API key needed. Only models we can actually serve are listed.
Available models
Models accessible through the API
Could not load the live model list. See GET https://api.tunai.tn/v1/models.
Error codes
Errors are returned in OpenAI's { error: { message, type, code } } shape
400invalid_request_errorInvalid parameter — `param` names the offending field.401invalid_request_errorMissing, invalid, revoked, or expired API key.402insufficient_quotaOut of balance, or the key hit its monthly budget.403invalid_request_errorThis key isn't permitted to use that endpoint.404invalid_request_errorUnknown model id or route.429rate_limit_errorRate limit exceeded for this key.502 / 503api_errorUpstream provider error or temporarily unavailable.Best practices
- •Keep your key secret: never commit it or expose it in client-side code.
- •Handle 429s: back off and retry on rate limits.
- •Watch your balance: a 402 means you're out of credits — top up to resume.
- •Pick the right model: cheaper models for simple tasks keeps costs down.