API reference
Kymo exposes an OpenAI-compatible chat completions API. Any OpenAI or Groq SDK works by changing the base URL to /api/public/v1.
Quickstart
Create an API key on the API keys page, then call the endpoint:
curl https://your-kymo-domain/api/public/v1/chat/completions \
-H "Authorization: Bearer $KYMO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b-versatile",
"messages": [
{ "role": "system", "content": "You are a concise assistant." },
{ "role": "user", "content": "What is an LPU?" }
],
"temperature": 0.7
}'Or with the OpenAI Python SDK:
from openai import OpenAI
client = OpenAI(
api_key=os.environ["KYMO_API_KEY"],
base_url="https://your-kymo-domain/api/public/v1",
)
completion = client.chat.completions.create(
model="openai/gpt-oss-120b",
messages=[{"role": "user", "content": "Write a haiku about latency."}],
)
print(completion.choices[0].message.content)Authentication
Send your key as a bearer token: Authorization: Bearer kymo_…. Keys are stored only as SHA-256 hashes, so the full value is shown exactly once at creation. Revoked keys immediately return 401.
Chat completions
POST /api/public/v1/chat/completions
model— required, see Models.messages— required array of system/user/assistant messages.temperature,top_p,max_tokens,stop— optional sampling controls.stream— boolean, emits server-sent events.response_format—{ "type": "json_object" }for JSON mode.
GET /api/public/v1/models lists the available models in OpenAI format.
Streaming
Set stream: true to receive incremental deltas as SSE. The stream ends with data: [DONE].
const res = await fetch(BASE_URL + "/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KYMO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "llama-3.3-70b-versatile",
messages: [{ role: "user", content: "Count to five." }],
stream: true,
}),
});
// Server-sent events: data: {...}\n\n ... terminated by data: [DONE]
const reader = res.body!.getReader();JSON mode
JSON mode guarantees syntactically valid JSON. Describe the exact shape you want in a system message, and avoid combining it with streaming.
{
"model": "llama-3.3-70b-versatile",
"response_format": { "type": "json_object" },
"messages": [
{ "role": "system", "content": "Reply with JSON: { title, tags[] }" },
{ "role": "user", "content": "Summarise the article about GPUs." }
]
}Vision
Vision-capable models accept an array content block with image URLs or base64 data URLs. Up to 5 images per request, 20 MB each.
{
"model": "qwen/qwen3.6-27b",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "What is in this image?" },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
}]
}Models
llama-3.3-70b-versatileGeneral-purpose workhorse. Fast, strong at reasoning and long-form text.
openai/gpt-oss-120bLarge open-weight model for demanding reasoning and code tasks.
qwen/qwen3.6-27bMultimodal: image understanding, OCR, captioning, visual Q&A.
groq/compoundAgentic system with built-in web search, page visits, and code execution.
groq/compound-miniSingle tool call per request, ~3x lower latency than Compound.
Rate limits & errors
Each API key is limited to 60 requests per rolling 60-second window. Exceeding it returns 429.
400— invalid body or unknown model.401— missing, invalid or revoked key.429— rate limit exceeded.502— upstream inference error.
Every request is recorded on your usage dashboard, including failures.