> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sideren.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat Completions.

> The OpenAI Chat Completions dialect on the Sideren catalog. If your client speaks to OpenAI, it speaks to Sideren — swap the base URL and the key, keep everything else.

## Endpoint

```http theme={null}
POST /v1/chat/completions
```

Authenticate with `Authorization: Bearer sdn_...`. Any model in the
[catalog](/models) is valid in `model`.

## Request parameters

| Parameter | Type | Notes |
| - | - | - |
| `model` | string · required | Any catalog id, e.g. `@sdn/gpt-oss-120b`. |
| `messages` | array · required | Chat history. Content can be a string or content parts; image parts (`image_url`, data URLs included) are accepted on vision models. |
| `max_tokens` | integer | Output ceiling. On reasoning models, hidden reasoning counts against it — budget generously. |
| `temperature` | number | Sampling temperature. |
| `top_p` | number | Nucleus sampling. |
| `stop` | string \| string\[] | Stop sequences. |
| `stream` | boolean | SSE chunks when `true`. See [Streaming](/guides/streaming). |
| `stream_options` | object | `{ "include_usage": true }` appends a final usage chunk. |
| `tools` | array | Function tools, carried exactly as sent. See [Tool calling](/guides/tool-calling). |
| `tool_choice` | string \| object | `auto`, `none`, `required`, or a named function. |
| `response_format` | object | JSON mode / `json_schema`. See [Structured output](/guides/structured-output). |
| `reasoning_effort` | string | Opt into visible reasoning and set the level. Returned on `choices[].message.reasoning_content`. See [Reasoning](/guides/reasoning). |
| `user` | string | A conversation-stable identity hint used for cache affinity — `prompt_cache_key` is accepted for the same purpose. See [Prompt caching](/guides/prompt-caching). |

## Example

<CodeGroup>
  ```sh curl theme={null}
  curl https://api.sideren.io/v1/chat/completions \
    -H "authorization: Bearer $SIDEREN_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "model": "@sdn/gpt-oss-120b",
      "messages": [
        { "role": "system", "content": "You are concise." },
        { "role": "user", "content": "Say hi." }
      ]
    }'
  ```

  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://api.sideren.io/v1",
      api_key="sdn_your_key",
  )

  r = client.chat.completions.create(
      model="@sdn/gpt-oss-120b",
      messages=[
          {"role": "system", "content": "You are concise."},
          {"role": "user", "content": "Say hi."},
      ],
  )
  print(r.choices[0].message.content)
  ```

  ```ts TypeScript theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    baseURL: "https://api.sideren.io/v1",
    apiKey: process.env.SIDEREN_API_KEY,
  });

  const r = await client.chat.completions.create({
    model: "@sdn/gpt-oss-120b",
    messages: [
      { role: "system", content: "You are concise." },
      { role: "user", content: "Say hi." },
    ],
  });
  console.log(r.choices[0].message.content);
  ```
</CodeGroup>

```json title="Response (shape)" theme={null}
{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "model": "@sdn/gpt-oss-120b",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "Hi." },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 14, "completion_tokens": 3, "total_tokens": 17 }
}
```

## Response fields

| Field | Notes |
| - | - |
| `choices[].message` | The assistant turn — `content`, and `tool_calls` when the model calls a tool. |
| `choices[].finish_reason` | `stop`, `length` (hit `max_tokens`), or `tool_calls`. |
| `usage` | Prompt, completion, and total token counts for the request. |

## Streaming

With `stream: true` the response is Server-Sent Events: incremental
`chat.completion.chunk` objects, terminated by `data: [DONE]`.

<CodeGroup>
  ```sh curl theme={null}
  curl -N https://api.sideren.io/v1/chat/completions \
    -H "authorization: Bearer $SIDEREN_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "model": "@sdn/gpt-oss-120b",
      "stream": true,
      "stream_options": { "include_usage": true },
      "messages": [{ "role": "user", "content": "Count to five." }]
    }'
  ```

  ```python Python theme={null}
  stream = client.chat.completions.create(
      model="@sdn/gpt-oss-120b",
      messages=[{"role": "user", "content": "Count to five."}],
      stream=True,
  )
  for chunk in stream:
      if chunk.choices and chunk.choices[0].delta.content:
          print(chunk.choices[0].delta.content, end="")
  ```

  ```ts TypeScript theme={null}
  const stream = await client.chat.completions.create({
    model: "@sdn/gpt-oss-120b",
    messages: [{ role: "user", content: "Count to five." }],
    stream: true,
  });
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  }
  ```
</CodeGroup>

## Errors

Failures return standard status codes with OpenAI-shaped bodies — match on the status,
retry on `429`/`5xx` with backoff. Full reference: [Errors](/errors).

<Note>
  Requesting vision input on a text-only model is a `400`. Image input is a short list —
  check `capabilities.vision` on [`GET /v1/models`](/api/models-endpoint) before you send.
  See [Vision](/guides/vision).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.