---
title: "Create a chat completion"
method: POST
path: "/chat/completions"
tags: ["Chat"]
---

# Create a chat completion

`POST /chat/completions`

## Request

- Base URL: `https://api.openscale.so/v1`
- URL: `https://api.openscale.so/v1/chat/completions`
- Auth: HTTP bearer

Send a conversation and receive the next assistant message. Set `stream: true` for Server-Sent Events. Models that reason return their reasoning in `reasoning_content` alongside `content`; when replaying a tool-calling conversation, send `reasoning_content` back on the assistant messages.

## Request body

- ChatCompletionRequest
  - `model` 'deepseek/deepseek-v4.1-flash' | 'z-ai/glm-5.3-flash' | 'deepseek/deepseek-v4.1-flash-1017' | 'deepseek/deepseek-v4.1-flash-0910' | 'z-ai/glm-5.3-flash-0828' | 'deepseek/deepseek-v4.1-flash:fast' | 'deepseek/deepseek-v4.1-flash-1017:fast' | 'deepseek/deepseek-v4.1-flash-0910:fast', required: A chat model id from `GET /models`.
  - `messages` Message[], required
    - `role` 'system' | 'user' | 'assistant' | 'tool', required
    - `content` union, required: Text, or an array of content parts for multimodal input.
      - string
      - object[]
        - `type` 'text' | 'image_url'
        - `text` string
        - `image_url` object
          - `url` string
    - `name` string
    - `tool_call_id` string
    - `tool_calls` ToolCall[]
      - `id` string
      - `type` 'function'
      - `function` object
        - `name` string
        - `arguments` string: JSON-encoded arguments.
    - `reasoning_content` string: The model's reasoning from a previous turn. Send it back on assistant messages when replaying a tool-calling conversation.
  - `stream` boolean: Stream the completion as Server-Sent Events. The final chunk before `[DONE]` carries `usage`.
  - `stream_options` object
    - `include_usage` boolean
  - `max_tokens` integer: Maximum completion tokens, including reasoning tokens. Reasoning models spend part of this budget thinking, so allow room for it. Above the model's output limit the request is refused with `max_tokens_exceeded`.
  - `max_completion_tokens` integer: Same as `max_tokens` (the newer OpenAI name).
  - `temperature` number
  - `top_p` number
  - `stop` union
    - string
    - string[]
  - `tools` object[]: OpenAI-style function tools.
    - `type` 'function'
    - `function` object
      - `name` string
      - `description` string
      - `parameters` object
  - `tool_choice` union
    - 'none' | 'auto' | 'required'
    - object
  - `response_format` object: Structured outputs: `json_object` or `json_schema`. `json_object` works whether or not your prompt mentions JSON.
    - `type` 'text' | 'json_object' | 'json_schema'
    - `json_schema` object
  - `reasoning` object: Reasoning control (OpenRouter style). `enabled: false` turns reasoning off; `effort` sets how much the model thinks; `exclude: true` keeps reasoning out of the reply.
    - `enabled` boolean
    - `effort` 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'
    - `exclude` boolean
  - `reasoning_effort` 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh': How much the model reasons before answering (OpenAI style); `none` turns reasoning off.
  - `logprobs` boolean
  - `top_logprobs` integer
  - `frequency_penalty` number
  - `presence_penalty` number
  - `user` string
  - `service_tier` string: `priority` runs the request in fast mode (same model, faster serving, higher price) when it is available; any other value runs at the standard tier. The response reports the tier that served it.

## Response `200`

The completion, or an SSE stream when `stream` is true.

- ChatCompletion
  - `id` string
  - `object` 'chat.completion'
  - `created` integer
  - `model` 'deepseek/deepseek-v4.1-flash' | 'z-ai/glm-5.3-flash' | 'deepseek/deepseek-v4.1-flash-1017' | 'deepseek/deepseek-v4.1-flash-0910' | 'z-ai/glm-5.3-flash-0828' | 'deepseek/deepseek-v4.1-flash:fast' | 'deepseek/deepseek-v4.1-flash-1017:fast' | 'deepseek/deepseek-v4.1-flash-0910:fast'
  - `choices` object[]
    - `index` integer
    - `message` object
      - `role` 'assistant'
      - `content` string, nullable
      - `reasoning_content` string: The model's reasoning, when it reasons before answering.
      - `tool_calls` ToolCall[]
        - `id` string
        - `type` 'function'
        - `function` object
          - `name` string
          - `arguments` string: JSON-encoded arguments.
    - `finish_reason` 'stop' | 'length' | 'tool_calls' | 'null', nullable
  - `usage` Usage
    - `prompt_tokens` integer
    - `completion_tokens` integer
    - `total_tokens` integer
    - `prompt_tokens_details` object
      - `cached_tokens` integer: Prompt tokens billed at the cached rate.
    - `completion_tokens_details` object
      - `reasoning_tokens` integer: Reasoning tokens, billed as completion tokens.
  - `service_tier` 'default' | 'priority': The tier that served the request: `priority` in fast mode.

## Other responses

- `400`: Invalid request: `invalid_messages`, `max_tokens_exceeded`, `invalid_reasoning_effort`, `context_length_exceeded` or `request_rejected`.
- `401`: Missing or invalid API key.
- `402`: Empty balance, or the key reached its spend limit.
- `404`: Unknown model id.
- `429`: Rate limit crossed or model at capacity.
- `502`: The model is temporarily unavailable.
- `504`: The model did not respond in time.

---

[API](https://skmtc.dev/openscale/apis/openscale-api.md) - [All operations](https://skmtc.dev/openscale/apis/openscale-api/llms.txt) - [OpenAPI document](https://skmtc.dev/openscale/apis/openscale-api/revisions/587e72b44932?raw)
