# Chat completions

> Every request parameter and response field of POST /v1/chat/completions.

```text
POST https://api.clonvo.com/v1/chat/completions
```

Creates a model response for a conversation. The request and response follow OpenAI’s Chat Completions API. Fields marked **Extension** are Clonvo or OpenRouter additions; the OpenAI SDKs pass them through with `extra_body` (Python) or as extra properties (Node.js).

## Request body

### Required

| Parameter | Type | Description |
| --- | --- | --- |
| `model` | string | Model id, such as `anthropic/claude-sonnet-5-5`. See [Models and model ids](https://clonvo.com/docs/models.md). |
| `messages` | array | The conversation so far. See [Messages](#messages). |

### Generation

| Parameter | Type | Description |
| --- | --- | --- |
| `max_completion_tokens` | integer | Upper bound on generated tokens, including reasoning tokens. |
| `max_tokens` | integer | Older name for the same limit. |
| `temperature` | number | Sampling temperature. Some models clamp it to a lower maximum. |
| `top_p` | number | Nucleus sampling. |
| `top_k` | integer | **Extension.** Top-k sampling. Sent to Anthropic (when reasoning is off), Gemini and free models. |
| `stop` | string or array | Sequences where generation stops. |
| `seed` | integer | Best-effort deterministic sampling, where supported. |
| `presence_penalty` | number | Penalise tokens that have already appeared. |
| `frequency_penalty` | number | Penalise tokens by how often they’ve appeared. |
| `repetition_penalty` | number | **Extension.** Repetition penalty. Sent to free models only. |
| `logit_bias` | object | Map of token id to bias, where supported. |
| `logprobs` | boolean | Return log probabilities of output tokens, where supported. |
| `top_logprobs` | integer | Number of most likely tokens to return at each position. |
| `n` | integer | Only `1` is supported. Other values return `400`; send separate requests for more completions. |
| `verbosity` | string | `low`, `medium` or `high`. OpenAI models that accept it. |

Sampling parameters a provider doesn’t support are dropped silently rather than rejected. Values outside the ranges OpenAI allows (for example `temperature` above 2) return `400`. Each model page lists the parameters its provider honours. Unknown top-level fields are ignored.

### Tools

| Parameter | Type | Description |
| --- | --- | --- |
| `tools` | array | Functions the model may call. See [Tool calling](https://clonvo.com/docs/tool-calling.md). |
| `tool_choice` | string or object | `auto`, `none`, `required`, or `{"type": "function", "function": {"name": "…"}}`. Values a model can’t honour become `auto`. |
| `parallel_tool_calls` | boolean | Allow several tool calls in one turn. Not sent to Gemini, DeepSeek or Moonshot models. |

### Output format

| Parameter | Type | Description |
| --- | --- | --- |
| `response_format` | object | `{"type": "text"}`, `{"type": "json_object"}` or `{"type": "json_schema", "json_schema": {…}}`. See [Structured outputs](https://clonvo.com/docs/structured-outputs.md). |

### Reasoning

| Parameter | Type | Description |
| --- | --- | --- |
| `reasoning_effort` | string | `none`, `minimal`, `low`, `medium`, `high`, `xhigh` or `max`. Each model accepts a subset. |
| `reasoning` | object | **Extension** (OpenRouter style): `effort`, `max_tokens`, `exclude`, `enabled`. Takes precedence over `reasoning_effort`. See [Reasoning](https://clonvo.com/docs/reasoning.md). |

### Streaming

| Parameter | Type | Description |
| --- | --- | --- |
| `stream` | boolean | Send the response as server-sent events. See [Streaming](https://clonvo.com/docs/streaming.md). |
| `stream_options` | object | `{"include_usage": true}`, accepted for OpenAI compatibility. Streams always end with a usage chunk. |

### Routing and billing

| Parameter | Type | Description |
| --- | --- | --- |
| `models` | array of strings | **Extension.** Fallback models, tried in order after `model`. See [Fallbacks and routing](https://clonvo.com/docs/fallbacks.md). |
| `provider.data_collection` | `"allow"` or `"deny"` | **Extension.** `deny` excludes endpoints that may store or train on prompts. |
| `provider.order` | array of strings | **Extension.** `"byok"` and `"credits"`, in the order to try them. Other entries are ignored. See [Choosing per request](https://clonvo.com/docs/fallbacks.md#choosing-per-request). |
| `provider.allow_fallbacks` | boolean | **Extension.** With `provider.order`, set `false` to use only the kinds listed there. It doesn’t affect `models`. |
| `usage.include` | boolean | **Extension.** Accepted for OpenRouter compatibility and has no effect: usage is always included. |

### Metadata

| Parameter | Type | Description |
| --- | --- | --- |
| `user` | string | Your identifier for the end user. Passed to OpenAI, xAI, Anthropic and free models; not stored by Clonvo. |
| `metadata` | object | String key-value pairs. Accepted for OpenAI compatibility; Clonvo doesn’t forward or store it. |
| `service_tier` | string | Accepted for OpenAI compatibility; not forwarded to providers. |

To name your app in [`GET /v1/generation`](https://clonvo.com/docs/other-endpoints.md#get-v1-generation) and the dashboard’s activity, send the `HTTP-Referer` and `X-Title` headers. See [App attribution](https://clonvo.com/docs/openai-sdks.md#app-attribution).

## Messages

Each message has a `role` and `content`:

| Role | Content |
| --- | --- |
| `system` / `developer` | Instructions. `developer` is mapped to `system` for models that don’t accept it. |
| `user` | A string, or an array of [content parts](https://clonvo.com/docs/images-and-files.md): `text`, `image_url`, `input_audio`, `file`. |
| `assistant` | A string, or `null` with `tool_calls`. May include `reasoning` from a previous turn (see [Reasoning](https://clonvo.com/docs/reasoning.md#multi-turn-conversations)). |
| `tool` | The result of a tool call, with `tool_call_id`. |

Text parts may carry `cache_control: {"type": "ephemeral"}` (with an optional `ttl` of `5m` or `1h`) to mark a prompt cache breakpoint for Anthropic models. **Extension.**

## Response

```json
{
  "id": "gen-01M67FGKKVQ8ZK2M3N5P7R9S1V",
  "object": "chat.completion",
  "created": 1793400000,
  "model": "anthropic/claude-sonnet-5-5",
  "provider": "Anthropic",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Here’s a summary…"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1200,
    "completion_tokens": 310,
    "total_tokens": 1510,
    "prompt_tokens_details": { "cached_tokens": 1024, "cache_write_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 },
    "cost": 0.0035544,
    "is_byok": false
  }
}
```

| Field | Description |
| --- | --- |
| `id` | Generation id (`gen-…`), also sent in the `x-clonvo-generation-id` header. Use it with [`GET /v1/generation`](https://clonvo.com/docs/other-endpoints.md#get-v1-generation). |
| `model` | The canonical id of the model that produced the response. It can differ from the `model` you sent: an alias resolves to its canonical id, and with fallbacks another model may answer. |
| `provider` | **Extension.** Display name of the provider that served the request, such as `Anthropic` or `Google AI Studio`. |
| `choices[].message.reasoning` | **Extension.** Reasoning text, when the model returns it. Left out otherwise, like `tool_calls` when there are none. |
| `choices[].finish_reason` | `stop`, `length`, `tool_calls`, `content_filter` or `error`. |
| `usage.prompt_tokens` | Input tokens, including cached and cache-write tokens. |
| `usage.completion_tokens` | Output tokens, including reasoning tokens. |
| `usage.prompt_tokens_details.cached_tokens` | Input tokens read from the provider’s prompt cache. |
| `usage.prompt_tokens_details.cache_write_tokens` | **Extension.** Input tokens written to the prompt cache. |
| `usage.completion_tokens_details.reasoning_tokens` | Tokens spent on reasoning. |
| `usage.cost` | **Extension.** What the request cost in US dollars at list price. |
| `usage.is_byok` | **Extension.** `true` when the request ran on your own provider key. |

On credits, `usage.cost` is exactly what’s deducted from your balance. On your own provider key, `usage.cost` is still the list price (what the request would have cost on credits), and `is_byok` is `true`; the provider bills you, and Clonvo’s fee is `0` within the [monthly allowance](https://clonvo.com/docs/byok.md#pricing). [`GET /v1/generation`](https://clonvo.com/docs/other-endpoints.md#get-v1-generation) shows the amount actually deducted. Free models report `0`.

## Cost

`usage.cost` is computed from the token counts and the model’s [list prices](https://clonvo.com/models.md):

```text
cost = (prompt − cached − cache_write) × prompt price
     + cached × cache read price
     + cache_write × cache write price
     + completion × completion price
     + per-request and web search charges, where the model has them
```

Prices are per 1M tokens; models with prompt-length tiers or peak hours use the price that applied to the request.
