For AI agents: markdown of this page — /docs-content-en/ai/chat/completions.md documentation index — /llms.txt
Create a chat completion
The response arrives in raw OpenAI format.
The
{success, data}wrapper used in the other Vibecode endpoints —/v1/deals,/v1/tasksand others — is absent here.This is done for compatibility with the OpenAI SDK. If you have a single client that checks
if (!response.success), add an exception for the AI Router.
POST /v1/chat/completions
Generates an AI model's response to an array of messages. The request and response format is compatible with POST /v1/chat/completions from the OpenAI API.
The endpoint's capabilities are documented on separate pages: streaming, guaranteed JSON response, function calling, image analysis and rate limits.
Request fields (body)
| Field | Type | Req. | Default | Description |
|---|---|---|---|---|
model |
string | no | auto |
Model ID or alias. See the "Model aliases" section below. If the field is not passed or equals auto, the request runs on the Bitrix24 account's default model. The list of available models — GET /v1/models |
messages |
array | yes | — | Array of conversation messages. Minimum 1, maximum 256 |
messages[].role |
string | yes | — | Role: system, user, assistant, tool |
messages[].content |
string | array | null | yes | — | Message text. Maximum 500,000 characters in a single message or 64 elements in the content array. For requests with images — an array with type: "text" and type: "image_url". An assistant message with tool_calls may have null content |
messages[].name |
string | no | — | Sender name (multi-agent scenarios) |
messages[].tool_calls |
array | no | — | Function calls from the assistant — present in the model's response when finish_reason: "tool_calls" |
messages[].tool_call_id |
string | no | — | Function call ID — required in a message with role: "tool" |
temperature |
number | no | per model | Generation temperature, range 0..2. Lower values are more precise and deterministic, higher values are more creative |
max_tokens |
number | no | per model | Maximum tokens in the response |
top_p |
number | no | — | Nucleus sampling, range 0..1 |
stop |
string | array | no | — | Stop sequences (up to 4, each up to 64 characters) |
stream |
boolean | no | false |
If true — the response arrives as a stream of Server-Sent Events |
response_format |
object | no | — | Control the response format: {"type": "text"} — the default, {"type": "json_object"} — valid JSON, {"type": "json_schema", "json_schema": {...}} — strict JSON Schema, requires model support |
tools |
array | no | — | Definitions of functions the model may call |
tool_choice |
string | object | no | — | auto (the model decides on its own), none (forbid calls) or {"type": "function", "function": {"name": "..."}} (force a specific one) |
Model aliases
The model field accepts three values that resolve to the Bitrix24 account's default model (currently bitrix/bitrixgpt-5.5): auto, bitrix/free and an empty string.
The models bitrix/bitrixgpt-5 and bitrix/bitrixgpt-5-vl are marked as deprecated and work until July 31, 2026. After that date, requests to them are transparently redirected to bitrix/bitrixgpt-5.5 with the X-Model-Replacement header — see model lifecycle for details.
In addition, a partial modelId is matched against the catalog by substring: if you pass gpt-4o-mini, the platform picks a model available to your key whose identifier contains that substring.
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/chat/completions \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bitrix/bitrixgpt-5.5",
"messages": [
{"role": "system", "content": "You are a sales expert. Classify leads by quality."},
{"role": "user", "content": "Acme LLC, 50 users, budget 500 thousand per month."}
],
"temperature": 0.3,
"max_tokens": 300
}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/chat/completions \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "bitrix/bitrixgpt-5.5",
"messages": [
{"role": "system", "content": "You are a sales expert. Classify leads by quality."},
{"role": "user", "content": "Acme LLC, 50 users, budget 500 thousand per month."}
],
"temperature": 0.3,
"max_tokens": 300
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/chat/completions', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'bitrix/bitrixgpt-5.5',
messages: [
{ role: 'system', content: 'You are a sales expert. Classify leads by quality.' },
{ role: 'user', content: 'Acme LLC, 50 users, budget 500 thousand per month.' },
],
temperature: 0.3,
max_tokens: 300,
}),
})
const data = await res.json()
console.log(data.choices[0].message.content)
console.log('Tokens:', data.usage.total_tokens)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/chat/completions', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'bitrix/bitrixgpt-5.5',
messages: [
{ role: 'system', content: 'You are a sales expert. Classify leads by quality.' },
{ role: 'user', content: 'Acme LLC, 50 users, budget 500 thousand per month.' },
],
temperature: 0.3,
max_tokens: 300,
}),
})
const data = await res.json()
console.log(data.choices[0].message.content)
Response fields
| Field | Type | Description |
|---|---|---|
id |
string | Unique completion ID for tracking |
object |
string | Always chat.completion for a synchronous response |
created |
number | Unix timestamp of the completion's creation |
model |
string | The model actually used (may differ from the request's model on automatic fallback to a backup model or a DISABLED redirect) |
choices |
array | The model's response variants. Without the n parameter the array has a single element |
choices[].index |
number | Variant ordinal number |
choices[].finish_reason |
string | Reason the generation finished: stop, length, tool_calls, content_filter |
choices[].message |
object | The generated message |
choices[].message.role |
string | Always assistant |
choices[].message.content |
string | null | Response text. null when finish_reason: "tool_calls" — the content is in tool_calls |
choices[].message.tool_calls |
array | List of function calls (if the model decided to call them) |
warnings |
array | Warnings about what the platform changed in the request or what to account for in the response. Every element carries at least code and message, some warnings add more fields. Known codes: MAX_TOKENS_RAISED, COWORK_QUOTA_FALLBACK (also carries tier, nextTier, resetAt), THINKING_TRUNCATED. The field is absent when there are no warnings |
usage.prompt_tokens |
number | Input tokens |
usage.completion_tokens |
number | Response tokens |
usage.total_tokens |
number | Sum of tokens in the request and response |
Response example
{
"id": "chatcmpl-a1a73c6eb3f180fd",
"object": "chat.completion",
"created": 1777289339,
"model": "bitrix/bitrixgpt-5.5",
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "Quality: HIGH\n\nRationale:\n- Legal entity (LLC) — B2B client\n- Budget 500 thousand per month — above average\n- Specific volume (50 users) — a deliberate need\n\nRecommendation: schedule a call within 24 hours."
}
}
],
"usage": {
"prompt_tokens": 42,
"completion_tokens": 85,
"total_tokens": 127
}
}
Error response example
404 ai_model_not_found — model not found or the key has no access to it:
{
"error": {
"message": "Model \"anthropic/claude-imaginary-x\" not found or disabled.",
"type": "invalid_request_error",
"code": "ai_model_not_found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | invalid_request |
Empty messages array, invalid role, schema violation |
| 400 | invalid_image_payload |
Invalid image_url — the message contains the content element index and the reason. See image analysis |
| 400 | no_default_model |
The portal has no models available to call |
| 402 | ai_credentials_not_configured |
No provider credentials for the model — connect BYOK |
| 402 | insufficient_balance |
Insufficient funds for a paid model |
| 402 | ai_quota_exhausted |
The portal's monthly AI quota is exhausted. The reason field clarifies the cause |
| 403 | scope_missing |
The API key is missing the vibe:ai scope |
| 404 | ai_model_not_found |
Model not found or disabled |
| 422 | structured_output_truncated |
A request with response_format did not produce a complete JSON: generation was cut off with finish_reason: "length", or the content field is empty with any finish reason and without tool_calls. The json_object mode has an exception — a complete JSON that landed in the service reasoning_content channel is recovered and the response stays 200. See guaranteed JSON response |
| 429 | rate_limit_exceeded |
The rate limit is exceeded. The X-RateLimit-Scope header indicates the level — per-key or per-user |
| 429 | ai_congested |
The AI cluster pool is overloaded. The request did not run and nothing was charged — retry it after the delay in the Retry-After header. The response carries the X-AI-Admission: shed header, not X-RateLimit-Scope |
| 429 | ai_pacing_limited |
A daily or weekly quota pacing window is exceeded. This is not quota exhaustion — retry the request after the delay in the Retry-After header. See Pacing (day/week smoothing) |
| 400 | ai_provider_rejected |
The model rejected the request itself (for example an unsupported parameter). Retrying it unchanged will not help. Returned when the provider responded with 400 or 422 |
| 502 | ai_provider_unavailable |
The external provider returned an error (401/403/5xx) or is unavailable |
| 503 | model_unavailable |
The model is disabled and no successor is assigned for it. See model lifecycle |
| 503 | pool_exhausted |
The platform is temporarily overloaded. Retry the request after the number of seconds in Retry-After — 3-7 seconds with random jitter |
The full list of common API errors — Errors.
Known specifics
Automatic fallback to a backup model on a provider failure. If a paid model returns a 5xx error or times out, the synchronous request is retried with the default model. The X-Model-Fallback: <original modelId> header appears in the response. In streaming mode there is no such fallback — the client receives an error in the last event before data: [DONE].
The Bitrix24 account's monthly AI quota. On Bitrix24 accounts with quota control enabled, a request may return 402 ai_quota_exhausted. The reason field distinguishes three cases: breaker — the hourly over-quota spending breaker tripped, wallet_empty — the quota is exhausted and the account balance has no funds, wallet_off — over-quota spend is not available for the account. The resetAt field holds the moment when requests will pass again. For wallet_off it may be absent. In the wallet_empty case the response may additionally carry a hint string and a topupUrl link to top up the balance — both fields appear when enforced quota control and the top-up hint are enabled on the platform, so read them as optional. The hint field in this response is a string. While usage stays within the quota, the endpoint's behavior is unchanged. Beyond the quota, if such spend is allowed for the account, requests are charged to the account's money balance at the model's base catalog price.
The processing budget for a synchronous request is about 850 seconds. Once the budget runs out, 503 ai_provider_timeout is returned. This response deliberately carries no Retry-After header: repeating the same request would hit the same budget. Reduce the request size or switch to streaming — there an idle timeout between events applies instead of a single budget for the whole call.
Request body size limit — 30 MiB. This is enough to pass a single image of up to 20 MiB: after base64 encoding it takes about 27 MiB.
Passing content as an array. For text models, pass content as a string. An array with a single text element also works but is redundant. An array is required only for requests with images.