---
title: "Create a chat completion (OpenAI-compatible)"
method: POST
path: "/api/v1/chat/completions"
tags: ["Batuta LLM"]
---

# Create a chat completion (OpenAI-compatible)

`POST /api/v1/chat/completions`

## Request

- Base URL: `https://getorquesta.com`
- URL: `https://getorquesta.com/api/v1/chat/completions`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

OpenAI-compatible chat completions endpoint. Pass any model id from `GET /models` as the
`model` field; pass the synthetic id `batuta-auto` to let Batuta classify the prompt and
route to a tier (fast / balanced / premium) automatically.

### Routing headers (optional)

  - `X-Batuta-Force-Tier: fast | balanced | premium` — bypass the classifier and pin a tier
    for this call. Only meaningful when `model = batuta-auto`.
  - `X-Batuta-Session-ID: <uuid>` — opaque session id. When provided, the proxy attributes
    prior assistant turns in this session to the model that produced them so downstream
    models can calibrate trust on cross-model conversations.

### Routing response headers

  - `X-Batuta-Routed-From: batuta-auto` (when input was routed)
  - `X-Batuta-Routed-To: <upstream-model-id>`
  - `X-Batuta-Tier: fast | balanced | premium`

## Headers

- `X-Batuta-Force-Tier` 'fast' | 'balanced' | 'premium'
- `X-Batuta-Session-ID` string, uuid

## Request body

- ChatCompletionRequest
  - `model` string, required: Any id returned by `GET /models`, or the synthetic `batuta-auto` to enable classifier-driven routing.
  - `messages` ChatMessage[], required
    - `role` 'system' | 'user' | 'assistant' | 'tool', required
    - `content` string, required
    - `name` string
    - `tool_calls` object[]
      - `id` string
      - `type` 'function'
      - `function` object
        - `name` string
        - `arguments` string: JSON-encoded arguments
    - `tool_call_id` string
  - `stream` boolean
  - `temperature` number
  - `max_tokens` integer
  - `tools` object[]
    - `type` 'function'
    - `function` object
      - `name` string
      - `description` string
      - `parameters` object: JSON Schema for the function arguments
  - `tool_choice` union
    - 'auto' | 'none' | 'required'
    - object
      - `type` 'function'
      - `function` object
        - `name` string

## Response `200`

Successful completion (or first SSE chunk if `stream=true`).

- ChatCompletionResponse
  - `id` string, required
  - `object` 'chat.completion', required
  - `created` integer, required: Unix epoch seconds
  - `model` string, required: The upstream model that actually generated the completion
  - `choices` object[], required
    - `index` integer
    - `message` ChatMessage
      - `role` 'system' | 'user' | 'assistant' | 'tool', required
      - `content` string, required
      - `name` string
      - `tool_calls` object[]
        - `id` string
        - `type` 'function'
        - `function` object
          - `name` string
          - `arguments` string: JSON-encoded arguments
      - `tool_call_id` string
    - `finish_reason` 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'null', nullable
  - `usage` object
    - `prompt_tokens` integer
    - `completion_tokens` integer
    - `total_tokens` integer

## Other responses

- `400`: Malformed request body (missing model, messages, etc.).
- `401`: Missing or invalid Batuta proxy token.
- `429`: Token quota exceeded for this billing tier.
- `500`: Internal proxy error or upstream failure.

---

[API](https://skmtc.dev/getorquesta/apis/orquesta-public-api.md) · [All operations](https://skmtc.dev/getorquesta/apis/orquesta-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getorquesta/apis/orquesta-public-api/revisions/7d27e0ae8324?raw)
