curl https://kymaapi.com/v1/chat/completions \
-H "Authorization: Bearer kyma-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
from openai import OpenAI
client = OpenAI(base_url="https://kymaapi.com/v1", api_key="kyma-your-api-key")
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Hello!"}]
)
Endpoints
Chat Completions
Generate a chat response from a model.
POST
/
v1
/
chat
/
completions
curl https://kymaapi.com/v1/chat/completions \
-H "Authorization: Bearer kyma-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
from openai import OpenAI
client = OpenAI(base_url="https://kymaapi.com/v1", api_key="kyma-your-api-key")
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Hello!"}]
)
Request body
string
required
Model ID to use. See available models.
array
required
Array of message objects with
role and content, forwarded to the model as sent.role:"system","user","assistant", or"tool"(a tool result)content: the message text, or an array of content parts (for exampleimage_urlparts on a vision model). See Tool calling.
number
Sampling temperature (0-2). Lower = more focused, higher = more creative. Kyma sets no default: when omitted, the model’s own default applies.
number
Maximum tokens to generate in the response. When omitted, the model’s own default applies. If your balance cannot pay for all of them, Kyma lowers the value and says so in the
x-kyma-max-tokens-clamped response header (see Response headers).boolean
default:"false"
Stream response tokens as server-sent events.
number
Nucleus sampling parameter (0-1). When omitted, the model’s own default applies.
array
Tool definitions, OpenAI format. On models with
supports_tools: true in GET /v1/models. Pair with tool_choice.object
{"type": "json_object"} or a json_schema, on models with supports_structured_outputs: true. See Structured outputs.stop, seed, stream_options, …) are forwarded to the model as sent. Kyma drops store and metadata. reasoning_effort and reasoning reach some models and are dropped for others.
Response
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1700000000,
"model": "qwen-3.6-plus",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 20,
"completion_tokens": 10,
"total_tokens": 30,
"cost": 0.0000393,
"cache_discount": 0
}
}
usage.cost is what the call cost you in USD; usage.cache_discount is what prompt caching saved on it.
Response headers
| Header | When |
|---|---|
x-kyma-model | Always. The model id your request resolved to |
x-kyma-alias | When you sent an alias; names it |
x-kyma-fallback | true when a fallback route or model answered |
x-kyma-served-model | Only when a different model answered; names it. Compare it with the model you asked for |
x-kyma-max-tokens-clamped | When your balance could not pay for the full max_tokens; the value Kyma sent instead. x-kyma-credits-have carries your balance |
Status codes
Every error body has a stringerror.code, a category in error.type, error.retryable and error.request_id (same as the x-request-id header). Branch on error.code; each code links to its entry on Errors.
| Status | error.code | Means | What to do |
|---|---|---|---|
400 | invalid_json, missing_parameter, invalid_parameter | The request is malformed | Fix it; retrying will not help |
400 | wrong_endpoint | The model belongs to another endpoint (an embedding, image or audio model); the message names it | Call that endpoint |
400 413 422 | request_rejected | The model rejected a parameter value, for example a temperature outside its range | Change the request; retrying the same body fails the same way |
401 | missing_api_key, invalid_api_key | No key, or an unknown or revoked key | Check the Authorization header |
402 | insufficient_credits, model_requires_paid | Your balance does not cover the request, or your account has never added credits and this model is not in the free tier | Top up, or pick a model with free_tier: true |
403 | route_refused | Every route for the model refused this content. error.suggested_models lists other models | Send it to one of the suggested models |
404 | model_not_found | Kyma does not serve that id. did_you_mean and suggested_models name close matches | Fix the model id |
413 | request_too_large | The body is over 25 MB | Split the messages or downscale images |
429 | rate_limit_exceeded | You hit your tier’s rate limit | Back off: Retry-After: 60, and x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests give the counts |
502 | upstream_invalid_response | The answer could not be fetched or read | Retry |
503 | provider_unavailable | Every route for the model is temporarily unavailable | Retry after Retry-After: 5, or use another model |
503 | model_unavailable | The model is not available on this endpoint right now | Pick another model |
402 is always about money or catalog access, never a problem on our side. Every 402 body carries need_usd and have_usd (on insufficient_credits), balance, required, topup_url, details and topup next to error. GET /v1/models publishes free_tier on every model, so a never-funded key can tell in advance which models it may call. Full bodies: Error Handling.
When all routes for a model are exhausted, you get 503 with Retry-After and:
{
"error": {
"message": "All providers for this model are temporarily unavailable. Please retry shortly.",
"type": "upstream_error",
"code": "provider_unavailable",
"param": null,
"retryable": true,
"request_id": "req_…",
"doc_url": "https://docs.kymaapi.com/api-reference/errors#provider_unavailable"
}
}
GET /v1/models.
If a stream fails after it started, the HTTP status is already 200: the last chunk has finish_reason: "error" and error.code: "stream_interrupted". Retry the whole request. See Errors while streaming.
curl https://kymaapi.com/v1/chat/completions \
-H "Authorization: Bearer kyma-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
from openai import OpenAI
client = OpenAI(base_url="https://kymaapi.com/v1", api_key="kyma-your-api-key")
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Hello!"}]
)