# Chat completions

> Run an agent turn — requests, the response shape, and the x_ravchat block.


<Warning>
`chat/completions` is now the **stateless fast surface**: fast mode is the
default and needs no selector. The legacy agentic behavior here
(`mode: "standard"` or `metadata.ravchat.session_id` hints) is **deprecated**
— responses carry `Deprecation` and `Sunset: Fri, 14 Aug 2026` headers, and
after the sunset those requests are refused. Stateful conversations live on
the [Stateful Agent API](/guides/agent-api).
</Warning>

`POST /v1/chat/completions` is OpenAI-compatible. **One request = one fast turn.**

```json
{
  "model": "ravchat",
  "messages": [
    {"role": "system", "content": "Answer with Chabad sources."},
    {"role": "user", "content": "What is bitachon?"}
  ],
  "stream": true,
  "stream_options": {"include_usage": true}
}
```

- **`model`** — see [Models](/guides/models). Unknown ids return 404 `model_not_found`.
- **`messages`** — `system` and `developer` messages are hoisted and concatenated as agent context. Prior turns render as a transcript; the final `user` message is the query. Text and `{type:"file"}` parts are supported; `image_url` / `input_audio` parts return 400.
- **Sampling parameters** (`temperature`, `top_p`, …) are accepted and ignored — the agent controls its own generation.
- **`tools` / `tool_choice`** return 400 in v1 (client-defined function calling is planned for v1.1).
- **`response_format`** with `json_schema` is enforced natively; see below.
- **`n`** must be 1.

## Structured output

`response_format` supports `text`, `json_object`, and strict `json_schema`. RavChat appends a JSON-only instruction (and, for schemas, the exact schema) so ordinary prompts conform without client-side coaching.

```python
completion = client.chat.completions.create(
    model="ravchat",
    messages=[{"role": "user", "content": "Give a source and its author."}],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "source",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {"source": {"type": "string"}, "author": {"type": "string"}},
                "required": ["source", "author"],
                "additionalProperties": False,
            },
        },
    },
)
```

<Note>
Schema-invalid output is **not** silently retried (a retry would be a second charged turn) — the turn is charged and returns an error.
</Note>

## Statelessness, sessions, and auto-create

Chat completions is stateless by default: each request starts a **fresh agent conversation** in your key's project. RavChat auto-creates whatever is missing:

- No project bound/named → your key's stable API project is created and reused (never a new project per request).
- No session named → a new session is created for the request.

The ids come back on every response (see [`x_ravchat`](#the-x-ravchat-block)), so the very first call needs zero setup.

**Opt-in continuity** — pass explicit hints to continue a live session with only your last message (requires `sessions:write`):

```json
"metadata": {"ravchat": {"session_id": "sess_...", "project_id": "..."}}
```

On an affinity hit your resent history is ignored (the agent has its own memory of the session). If the hinted session is gone, the request falls back to a fresh conversation and `x_ravchat.created.session` tells you.

## Response

A standard `chat.completion` object — single choice, `message.content`, `finish_reason` (`stop` | `length`), `usage` — plus:

- **`usage.cost`** — RavChat credits charged for the turn (billing-authoritative). Non-streaming responses also carry it in the `x-ravchat-credits` header.
- **`x_ravchat`** — the context block.

### The x_ravchat block

```json
"x_ravchat": {
  "project_id": "…", "workspace_id": "…", "session_id": "sess_…", "thread_id": "…",
  "created": {"project": false, "workspace": false, "session": true},
  "files": [
    {"id": "file-rav-…", "object": "file", "filename": "summary.md", "bytes": 4812,
     "purpose": "assistants_output", "source": "assistant"}
  ]
}
```

`files[]` lists files the agent was **observed** producing during the turn (shown files and generated media — see [Files](/guides/files) for the exact promise). Download any of them via `GET /v1/files/{id}/content`.

The same ids are always available as response headers — `x-ravchat-project-id`, `x-ravchat-session-id`, `x-ravchat-thread-id`, `x-ravchat-created-session`, and more — which survive proxies that strip unknown body fields (e.g. LiteLLM).
