OpenAI Compatibility
Tuna supports OpenAI's Chat Completions request format for the features listed below. To use an OpenAI-compatible client:
- Set the base URL to
https://api-us.tuna.ai/v1. - Use a Tuna API key.
- Select a model ID from Tuna's models.
Check the compatibility table below for the endpoints and features your application uses.
Point an OpenAI Client at Tuna
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api-us.tuna.ai/v1",
apiKey: "tuna_yourApiKeyHereWithTunaUnderscore",
});
const response = await client.chat.completions.create({
model: "tuna-us/example-lab/example-model-id",
messages: [{
role: "user",
content: "Is the tuna one of the fastest sustained swimming fish species? And does it have a streamlined body?",
}],
});
console.log(response.choices[0].message.content);
from openai import OpenAI
client = OpenAI(
base_url="https://api-us.tuna.ai/v1",
api_key="tuna_yourApiKeyHereWithTunaUnderscore",
)
response = client.chat.completions.create(
model="tuna-us/example-lab/example-model-id",
messages=[{
"role": "user",
"content": "Is the tuna one of the fastest sustained swimming fish species? And does it have a streamlined body?",
}],
)
print(response.choices[0].message.content)
curl https://api-us.tuna.ai/v1/chat/completions \
-H "Authorization: Bearer tuna_yourApiKeyHereWithTunaUnderscore" \
-H "Content-Type: application/json" \
-d '{"model": "tuna-us/example-lab/example-model-id", "messages": [{"role": "user", "content": "Is the tuna one of the fastest sustained swimming fish species? And does it have a streamlined body?"}]}'
The OpenAI SDKs also read the base URL and key from environment variables, and so do many tools built on them:
export OPENAI_BASE_URL="https://api-us.tuna.ai/v1"
export OPENAI_API_KEY="tuna_yourApiKeyHereWithTunaUnderscore"
Endpoint Compatibility Comparison
This table lists OpenAI SDK calls, and what happens when the client's base URL is Tuna's. The chat.completions.create calls go to POST /v1/chat/completions, and models.list goes to GET /v1/models.
| OpenAI SDK call | Supported | Docs |
|---|---|---|
chat.completions.create |
Yes | Chat completions, Streaming |
chat.completions.create with tools |
Yes | Tool calling |
chat.completions.create with image parts |
Yes | Image input |
chat.completions.create with reasoning_effort |
Yes | Reasoning effort |
chat.completions.create with response_format |
Coming soon | Structured outputs |
models.list |
Yes | List Model Endpoints |
responses.create |
No | Use chat completions. |
completions.create |
No | Use chat completions. |
assistants.*, threads.* |
No | Run the agent loop in your code with tool calling. |
embeddings.create |
No | |
images.*, audio.* |
No | |
moderations.create |
No | |
batches.*, files.*, fine_tuning.* |
No |
A call that isn't supported returns an error.
Supported features need no extra setup. Input caching is automatic, and cached tokens are counted in usage.prompt_tokens_details.cached_tokens, the same field OpenAI uses. See Input caching.
Differences from OpenAI
Model IDs
OpenAI model names like gpt-4o aren't available, because Tuna serves open-weight models. Use a Tuna id instead. Tuna's ids start with tuna-us/, then the model's maker and name, like tuna-us/moonshotai/kimi-k3-ultrafast. Get the current list from GET /v1/models.
Parameters
- If
max_tokensis higher than the model's own limit, Tuna lowers it to that limit instead of returning an error. max_completion_tokensis treated the same asmax_tokens.reasoning_effortonly has an effect on reasoning models. Some models accept more levels thanlow,medium, andhigh. See Reasoning effort.
Responses
- Reasoning models put their thinking in a
reasoningfield on the message, next tocontent. In a stream, it arrives indelta.reasoning. See Reasoning effort. - If a stream fails after it started, the last chunk has an
errorobject andfinish_reasoniserror. See Errors during a stream.
Errors
An error body has the form {"error": {"code": 401, "message": "..."}}. The code is the HTTP status as a number, and the message text is Tuna's own. Base error handling in your code on the HTTP status. The message text can change. See Errors.
Pricing
Writing to the input cache costs the same as normal input. OpenAI charges more than its input price for cache writes on some models. See Input caching.
Other Libraries
Most libraries and tools that let you set an OpenAI base URL work with Tuna too. See Recommended SDKs for the ones Tuna tests with.
