Core API
Chat Completions
Build non-streaming OpenAI-compatible chat requests and handle their responses.
On this page
This page is for developers implementing the primary CLSSAI text and multimodal conversation endpoint.
Send POST https://api.clssai.com/v1/chat/completions with a JSON body.
Request fields#
| Field | Type | Required | Gateway behavior |
|---|---|---|---|
model | string | yes | A complete callable ID or exact bare alias. Unknown bare names become openai/<name>. |
messages | array | yes | Forwarded in order to the selected model. |
stream | boolean | no | When true, the response is SSE. |
max_tokens | integer | no | Forwarded; model support and limits vary. |
temperature | number | no | Forwarded; model support and ranges vary. |
tools | array | no | Forwarded unchanged; support depends on the model. |
tool_choice | string or object | no | Forwarded unchanged; support depends on the model. |
user | string | no | If omitted, the gateway supplies an internal identifier derived from the key. |
Messages commonly use system, user, assistant, and tool roles. Text content can be a string. For a vision-capable model, content can be an array with text and image_url parts.
If you do not pass user, the gateway injects an internal identifier derived from your key; pass your own user to control what appears in /v1/responses echoes.
Non-streaming request#
curl https://api.clssai.com/v1/chat/completions \
-H "Authorization: Bearer $CLSSAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.4-nano",
"messages": [
{"role": "system", "content": "Answer concisely."},
{"role": "user", "content": "Name one benefit of server-side API calls."}
],
"max_tokens": 80
}'import os
from openai import OpenAI
client = OpenAI(base_url="https://api.clssai.com/v1", api_key=os.environ["CLSSAI_API_KEY"])
response = client.chat.completions.create(
model="openai/gpt-5.4-nano",
messages=[
{"role": "system", "content": "Answer concisely."},
{"role": "user", "content": "Name one benefit of server-side API calls."},
],
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.clssai.com/v1",
apiKey: process.env.CLSSAI_API_KEY,
});
const response = await client.chat.completions.create({
model: "openai/gpt-5.4-nano",
messages: [{ role: "user", content: "Name one benefit of server-side API calls." }],
});
console.log(response.choices[0].message.content);Response fields#
| Field | Meaning |
|---|---|
id | Upstream request or generation identifier. |
model | Model reported for the result. |
provider | Upstream provider selected for this response. |
system_fingerprint | Upstream system fingerprint, when reported. |
service_tier | Upstream service tier, when reported. |
choices | Candidate outputs and finish reasons. |
choices[].message | Assistant content or tool-call data. |
usage | Token accounting reported by the upstream API. |
usage.prompt_tokens_details | Prompt-token details, when reported, including cached_tokens, cache_write_tokens, audio_tokens, and video_tokens. |
usage.cost | Charge authority when supplied by the upstream API. |
usage.cost_details | Upstream cost breakdown, when reported. |
usage.is_byok | Upstream flag describing how that provider call was authenticated. |
{
"id": "gen_example",
"object": "chat.completion",
"model": "openai/gpt-5.4-nano",
"choices": [{"index": 0, "message": {"role": "assistant", "content": "It keeps the API key out of browser code."}, "finish_reason": "stop"}],
"usage": {"prompt_tokens": 22, "completion_tokens": 12, "total_tokens": 34}
}Prompt caching#
The OpenAI-compatible route uses upstream prompt caching automatically: an eligible long prompt prefix is reused on repeated requests. No request changes are required, and the gateway leaves all cache-related fields unchanged.
In a verified request with 4638 prompt tokens, the first response reported usage.prompt_tokens_details.cached_tokens = 0 and usage.cost = 0.00093385. Two subsequent requests kept the same prefix and changed only the user message; both reported cached_tokens = 3840 and usage.cost = 0.00024265, about 26% of the first request's cost. The returned usage.cost already reflects the cache discount, so clients do not need to calculate it themselves.
Multimodal input#
Use a URL or data URL only with a model whose input modalities include images.
{
"model": "google/gemini-2.5-flash",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image."},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,BASE64_DATA"}}
]
}]
}Pass-through#
Tool fields are forwarded unchanged. Confirm tools support in current model metadata and handle returned tool calls according to the OpenAI-compatible schema. The gateway does not promise that every model accepts every forwarded field.
Common mistakes#
- Include
/v1in the OpenAI SDK base URL. - Keep API keys and SDK calls on the server; a browser inference call exposes the key to every visitor.
- Prefer a complete
author/modelID in production and confirm bare-name resolution in the responsemodelfield. Preserve the fullauthor/model:freeorauthor/model:batchID. - Use the Anthropic SDK base URL without
/v1. - Check
choices.lengthbefore reading a streaming chunk. - Report
cf-raywhen asking support to trace a request.
Also available (pass-through, lightly tested)#
The Responses endpoint accepts an OpenAI-compatible request through the same authenticated /v1 base.
curl https://api.clssai.com/v1/responses \
-H "Authorization: Bearer $CLSSAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.4-nano","input":"Reply with OK."}'The legacy completions endpoint is passed through and current text chat models serve it, including models you would normally reach only through Chat Completions. A model of the wrong modality is rejected: embedding and speech models return 400 and image models return 404, both with a message naming the correct endpoint. Prefer Chat Completions for new work.
curl https://api.clssai.com/v1/completions \
-H "Authorization: Bearer $CLSSAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"meta-llama/llama-3.1-8b-instruct","prompt":"Reply with OK.","max_tokens":8}'A fallback models array is forwarded, but entries in that array are not alias-expanded. Write every entry as a full ID.
{"model":"openai/gpt-5.4-nano","models":["openai/gpt-5.4-nano","meta-llama/llama-3.1-8b-instruct"],"messages":[{"role":"user","content":"Reply with OK."}]}Find answers to common questions or diagnose a failed request.
Frequently asked questions →Troubleshoot errors →