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

# Create a chat completion

The OpenAI Chat Completions API: messages (text and, on models with `image_input`, images), tools and tool choice, `response_format` with JSON Schema, sampling parameters and streaming. With `stream: true` the response is server-sent events of `chat.completion.chunk` objects ending with `data: [DONE]`, exactly as OpenAI sends them; `stream_options.include_usage` adds a final usage chunk (and `"usage": null` on the others). A stream that fails after it started ends with an OpenAI error event (`data: {"error": {...}}`); one that fails before the first token is a plain HTTP error. The response head of a stream waits for the first generated token, so `Server-Timing` can carry `ttft`.
Parameters this node does not take return `400 unsupported_parameter` naming the parameter. Besides the OpenAI parameters below, it takes the sampling extensions `top_k`, `min_p`, `repetition_penalty` and `logit_bias`, and `chat_template_kwargs.enable_thinking` (the model answers without a reasoning phase unless it is `true`; the reasoning then arrives in `reasoning_content`). `metadata`, `store` and `service_tier` are accepted and ignored. `null` means unset for every optional parameter. Image URLs are `https://` (fetched by the node through its egress guard, which refuses private, loopback and metadata addresses with `403 egress_denied`) or `data:image/{png,jpeg,webp,gif};base64,`. JSON Schemas (tool `parameters`, `response_format.json_schema.schema`) larger than 64 KiB or nested deeper than 32 levels are `400 unsupported_parameter`.
Bills input and output tokens. Requests are admitted against your organization's per-minute limits on the model: one request, and the estimated prompt plus `max_completion_tokens` (or `max_tokens`, else 512 tokens), settled with the real counts when the request ends. 

` POST /v1/infer/chat/completions `

Create a chat completion

The OpenAI Chat Completions API: messages (text and, on models with `image_input`, images), tools and
tool choice, `response_format` with JSON Schema, sampling parameters and streaming. With `stream: true` the
response is server-sent events of `chat.completion.chunk` objects ending with `data: [DONE]`, exactly as
OpenAI sends them; `stream_options.include_usage` adds a final usage chunk (and `"usage": null` on the
others). A stream that fails after it started ends with an OpenAI error event
(`data: {"error": {...}}`); one that fails before the first token is a plain HTTP error. The response head
of a stream waits for the first generated token, so `Server-Timing` can carry `ttft`.

Parameters this node does not take return `400 unsupported_parameter` naming the parameter. Besides the
OpenAI parameters below, it takes the sampling extensions `top_k`, `min_p`, `repetition_penalty` and
`logit_bias`, and `chat_template_kwargs.enable_thinking` (the model answers without a reasoning phase
unless it is `true`; the reasoning then arrives in `reasoning_content`). `metadata`, `store` and
`service_tier` are accepted and ignored. `null` means unset for every optional parameter. Image URLs are
`https://` (fetched by the node through its egress guard, which refuses private, loopback and metadata
addresses with `403 egress_denied`) or `data:image/{png,jpeg,webp,gif};base64,`. JSON Schemas (tool
`parameters`, `response_format.json_schema.schema`) larger than 64 KiB or nested deeper than 32 levels are
`400 unsupported_parameter`.

Bills input and output tokens. Requests are admitted against your organization's per-minute limits on the
model: one request, and the estimated prompt plus `max_completion_tokens` (or `max_tokens`, else 512
tokens), settled with the real counts when the request ends.


## Servers

- ` https://beta-api.b3os.org ` — API (API keys and CLI tokens)

- ` https://beta.b3os.org ` — Dashboard (session cookie and CSRF header; same paths)

## Authentication

The operation accepts these alternatives. Schemes within one alternative are required together.

### Alternative 1

- ` apiKey `: ` http `

  - HTTP scheme: ` bearer ` (b3os_sk_ API key or b3os_pat_ token)

  - `Authorization: Bearer <credential>`. Two credential kinds are accepted:

- **API keys** `b3os_sk_<32 base32>_<crc32>`, created in the dashboard or with `POST /v1/keys`. A key belongs to
  one project, has scopes, an optional spend cap and expiry, and is shown only once.
- **CLI tokens** `b3os_pat_<32 base32>_<crc32>`, issued by the device login (`b3os login`). They act for one
  user in the organization and project chosen at approval.

Keys are stored as SHA-256 hashes. The edge exchanges them for a 60-second node token before forwarding
a request to a node, so nodes never see your key.


### Alternative 2

- ` session `: ` apiKey `

  - Credential: ` __Host-b3os_session ` in ` cookie `

  - The dashboard session cookie on `beta.b3os.org` (host-only, `Secure`, `HttpOnly`). Requests other than
`GET`/`HEAD` must also send `x-b3os-csrf: <csrf_token>` from `GET /v1/auth/session`; SameSite is not relied
on. The cookie is never sent to `beta-api.b3os.org` or `usercontent.b3os.org`.


## Request body (required)

Content type: ` application/json `

- ` value `: type ` object ` — OpenAI Chat Completions parameters, the runtime extensions this node takes, and `route`. Any other parameter is `400 unsupported_parameter`. `null` means unset for every optional parameter. 

  - Required fields: ` model `, ` messages `

  - ` model `: type ` string ` — A model ID from `GET /v1/infer/models`.

    - minLength: ` 1 `

    - maxLength: ` 256 `

  - ` messages `: type ` array `

    - ` array item `: type ` object ` — A message. `content` may be a string or a list of parts (images only in `user` messages); only `assistant` messages may have `null` content (`400 invalid_request` with the pointer otherwise). Members not listed here (such as `annotations` or `audio` echoed from an earlier response) are ignored. 

      - Required fields: ` role `

      - ` role `: type ` string `

        - enum: ` ["system","developer","user","assistant","tool"] `

      - ` content `: type ` unknown `

        - ` oneOf alternative 1 `: type ` string `; nullable

        - ` oneOf alternative 2 `: type ` array `

          - ` array item `: type ` unknown `

            - ` oneOf alternative 1 `: type ` object `

              - Required fields: ` type `, ` text `

              - ` type `: type ` string `

                - enum: ` ["text"] `

              - ` text `: type ` string `

            - ` oneOf alternative 2 `: type ` object `

              - Required fields: ` type `, ` image_url `

              - ` type `: type ` string `

                - enum: ` ["image_url"] `

              - ` image_url `: type ` object `

                - Required fields: ` url `

                - ` url `: type ` string ` — An `https://` URL (fetched by the node through its egress guard; PNG, JPEG, WebP or GIF, at most 10 MiB) or a `data:image/{png,jpeg,webp,gif};base64,` URL. Images are scaled to at most about one megapixel (about 1,024 prompt tokens each). 

                  - pattern: ` "^(https://|data:image/(png|jpeg|jpg|webp|gif);base64,)" `

                - ` detail `: type ` string `

                  - enum: ` ["auto","low","high"] `

      - ` name `: type ` string `; nullable

      - ` tool_calls `: type ` array `; nullable

        - ` array item `: type ` object `

          - Required fields: ` id `, ` type `, ` function `

          - ` id `: type ` string `

          - ` type `: type ` string `

            - enum: ` ["function"] `

          - ` function `: type ` object `

            - Required fields: ` name `, ` arguments `

            - ` name `: type ` string `

            - ` arguments `: type ` string ` — JSON-encoded arguments.

      - ` tool_call_id `: type ` string `; nullable — For `tool` messages, the call this is the result of.

      - ` refusal `: type ` string `; nullable

      - ` reasoning_content `: type ` string `; nullable — B3OS extension. The reasoning of an earlier assistant turn, passed back to the model's template.

  - ` tools `: type ` array `; nullable

    - ` array item `: type ` object `

      - Required fields: ` type `, ` function `

      - ` type `: type ` string `

        - enum: ` ["function"] `

      - ` function `: type ` object `

        - Required fields: ` name `

        - ` name `: type ` string `

          - pattern: ` "^[A-Za-z0-9_-]{1,64}$" `

        - ` description `: type ` string `

        - ` parameters `: type ` object ` — A JSON Schema object (at most 64 KiB serialized and 32 levels deep), as OpenAI requires.

        - ` strict `: type ` boolean `

  - ` tool_choice `: type ` unknown `

    - ` oneOf alternative 1 `: type ` string `; nullable

      - enum: ` ["none","auto","required"] `

    - ` oneOf alternative 2 `: type ` object `

      - Required fields: ` type `, ` function `

      - ` type `: type ` string `

        - enum: ` ["function"] `

      - ` function `: type ` object `

        - Required fields: ` name `

        - ` name `: type ` string `

  - ` parallel_tool_calls `: type ` boolean `; nullable

  - ` response_format `: type ` unknown `

    - ` oneOf alternative 1 `: type ` object `; nullable

      - Required fields: ` type `

      - ` type `: type ` string `

        - enum: ` ["text"] `

    - ` oneOf alternative 2 `: type ` object `

      - Required fields: ` type `

      - ` type `: type ` string `

        - enum: ` ["json_object"] `

    - ` oneOf alternative 3 `: type ` object `

      - Required fields: ` type `, ` json_schema `

      - ` type `: type ` string `

        - enum: ` ["json_schema"] `

      - ` json_schema `: type ` object `

        - Required fields: ` name `

        - ` name `: type ` string `

          - pattern: ` "^[A-Za-z0-9_-]{1,64}$" `

        - ` description `: type ` string `

        - ` schema `: type ` object ` — A JSON Schema object (at most 64 KiB serialized and 32 levels deep), as OpenAI requires.

        - ` strict `: type ` boolean `

  - ` temperature `: type ` number `; nullable

    - minimum: ` 0 `

    - maximum: ` 2 `

  - ` top_p `: type ` number `; nullable — Nucleus sampling. `0` keeps only the most probable token (passed to the runtime as 1e-9, the same thing, since vLLM takes values above 0 only).

    - minimum: ` 0 `

    - maximum: ` 1 `

  - ` max_tokens `: type ` integer `; nullable

    - minimum: ` 1 `

  - ` max_completion_tokens `: type ` integer `; nullable — Wins over `max_tokens` when both are set.

    - minimum: ` 1 `

  - ` stop `: type ` unknown `

    - ` oneOf alternative 1 `: type ` string `; nullable

    - ` oneOf alternative 2 `: type ` array `

      - ` array item `: type ` string `

  - ` seed `: type ` integer `; nullable

  - ` n `: type ` integer `; nullable — Only 1 is supported.

    - minimum: ` 1 `

    - maximum: ` 1 `

  - ` presence_penalty `: type ` number `; nullable

    - minimum: ` -2 `

    - maximum: ` 2 `

  - ` frequency_penalty `: type ` number `; nullable

    - minimum: ` -2 `

    - maximum: ` 2 `

  - ` logprobs `: type ` boolean `; nullable

  - ` top_logprobs `: type ` integer `; nullable

    - minimum: ` 0 `

    - maximum: ` 20 `

  - ` user `: type ` string `; nullable

  - ` stream `: type ` boolean `; nullable

    - default: ` false `

  - ` stream_options `: type ` object `; nullable

    - ` include_usage `: type ` boolean `; nullable

  - ` route `: type ` string `; nullable — B3OS extension. `gateway` sends the request to the B3IQ gateway when this node does not serve the model (models it serves stay local); without it an unknown model is `404 model_not_available`. 

    - enum: ` ["local","gateway",null] `

    - default: ` "local" `

  - ` top_k `: type ` integer `; nullable — Runtime extension. Sample from the `top_k` most likely tokens; `-1` turns it off.

    - minimum: ` -1 `

    - maximum: ` 1000000 `

  - ` min_p `: type ` number `; nullable — Runtime extension. Minimum probability relative to the most likely token.

    - minimum: ` 0 `

    - maximum: ` 1 `

  - ` repetition_penalty `: type ` number `; nullable — Runtime extension. Values above 1 discourage repeating tokens.

    - minimum: ` 0 `

    - maximum: ` 2 `

  - ` logit_bias `: type ` object `; nullable — Token ID to bias added to its logit.

  - ` chat_template_kwargs `: type ` object `; nullable — Runtime extension. Only `enable_thinking` is taken.

    - ` enable_thinking `: type ` boolean ` — Let the model reason before answering; the reasoning arrives in `reasoning_content`.

  - ` metadata `: type ` object `; nullable — Accepted and ignored.

  - ` store `: type ` boolean `; nullable — Accepted and ignored (nothing is stored).

  - ` service_tier `: type ` string `; nullable — Accepted and ignored.

## Responses

### ` 200 ` — The completion, or the chunk stream with `stream: true`.

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` id `, ` object `, ` created `, ` model `, ` choices `

  - ` id `: type ` string `

  - ` object `: type ` string `

    - enum: ` ["chat.completion"] `

  - ` created `: type ` integer ` — Unix seconds.

  - ` model `: type ` string `

  - ` choices `: type ` array `

    - ` array item `: type ` object `

      - Required fields: ` index `, ` message `, ` finish_reason `

      - ` index `: type ` integer `

      - ` message `: type ` object `

        - Required fields: ` role `, ` content `

        - ` role `: type ` string `

          - enum: ` ["assistant"] `

        - ` content `: type ` string `; nullable

        - ` tool_calls `: type ` array `

          - ` array item `: type ` object `

            - Required fields: ` id `, ` type `, ` function `

            - ` id `: type ` string `

            - ` type `: type ` string `

              - enum: ` ["function"] `

            - ` function `: type ` object `

              - Required fields: ` name `, ` arguments `

              - ` name `: type ` string `

              - ` arguments `: type ` string ` — JSON-encoded arguments.

        - ` refusal `: type ` string `; nullable

        - ` reasoning_content `: type ` string ` — B3OS extension. The model's reasoning, when `chat_template_kwargs.enable_thinking` is on.

      - ` finish_reason `: type ` string `

        - enum: ` ["stop","length","tool_calls","content_filter"] `

      - ` logprobs `: type ` object `; nullable

  - ` usage `: type ` object `

    - Required fields: ` prompt_tokens `, ` completion_tokens `, ` total_tokens `

    - ` prompt_tokens `: type ` integer `

    - ` completion_tokens `: type ` integer `

    - ` total_tokens `: type ` integer `

  - ` system_fingerprint `: type ` string `; nullable

  - ` b3os `: type ` object ` — B3OS extension; OpenAI SDKs ignore it. On a stream it rides on the last chunk: the usage chunk with `stream_options.include_usage`, else the chunk with `finish_reason`. 

    - ` route `: type ` string `

      - enum: ` ["local","gateway"] `

    - ` node `: type ` string `

    - ` timing `: type ` object ` — Server-side milliseconds from the request head (`ttft_ms` on streams, `model_ms` without).

      - ` ttft_ms `: type ` number `

      - ` model_ms `: type ` number `

      - ` total_ms `: type ` number `

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "id": "chatcmpl-01m5t5tmscqev5tf32q87tr1v5",
  "object": "chat.completion",
  "created": 1793001600,
  "model": "b3os/qwen3.5-9b",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_7f3a",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Eugene\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls",
      "logprobs": null
    }
  ],
  "usage": {
    "prompt_tokens": 61,
    "completion_tokens": 18,
    "total_tokens": 79
  },
  "b3os": {
    "route": "local",
    "node": "n1"
  }
}
```

### ` 400 ` — The request is invalid (`invalid_request`, `unsupported_parameter`, `context_length_exceeded`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "prompt_logprobs is not supported on this node",
    "type": "invalid_request_error",
    "param": "prompt_logprobs",
    "code": "unsupported_parameter"
  }
}
```

### ` 401 ` — Missing or invalid credentials (`unauthorized`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "API key checksum does not match; check that the whole key was copied",
    "type": "authentication_error",
    "param": null,
    "code": "unauthorized"
  }
}
```

### ` 403 ` — The key lacks `infer:run` or `infer:read` (`forbidden`), or the egress guard refused an image URL (`egress_denied`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

### ` 404 ` — The model is not served on this node (`model_not_available`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "gpt-5 is not served on this node; set \"route\":\"gateway\" to use the B3IQ gateway",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_available"
  }
}
```

### ` 413 ` — The request body exceeds the model's `max_request_bytes` (`payload_too_large`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "Request body is 12582912 bytes; this model accepts at most 10485760",
    "type": "invalid_request_error",
    "param": null,
    "code": "payload_too_large"
  }
}
```

### ` 415 ` — The body is not JSON (`unsupported_media_type`): send `Content-Type: application/json`.

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "expected Content-Type: application/json",
    "type": "invalid_request_error",
    "param": null,
    "code": "unsupported_media_type"
  }
}
```

### ` 429 ` — A limit applies (`rate_limited` for requests, tokens or remote image bytes per minute, `concurrency_limited` for requests in flight for the organization, `quota_exceeded`; `credits_exhausted` arrives as 402).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Response header ` RateLimit-Limit ` — Requests allowed in the current window for the limit that applies to this operation.

- ` value `: type ` integer `

Response header ` RateLimit-Remaining ` — Requests left in the current window.

- ` value `: type ` integer `

Response header ` RateLimit-Reset ` — Seconds until the current window resets.

- ` value `: type ` integer `

Example:

```json
{
  "error": {
    "message": "200000 tokens per minute allowed on b3os/qwen3.5-9b; retry in 9 seconds",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limited"
  }
}
```

### ` 500 ` — Something failed inside B3OS (`internal`).

Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Example:

```json
{
  "error": {
    "message": "internal error (request req_01m5t4yg394wegr3j4y01qb363)",
    "type": "server_error",
    "param": null,
    "code": "internal"
  }
}
```

### ` 503 ` — The model runtime, the voice service or the B3IQ gateway route is restarting, overloaded or not set up on
this node (`infer_backend_unavailable`, `capacity_unavailable`), or the node is unavailable
(`node_unavailable`).


Content type: ` application/json `

- ` value `: type ` object ` — The OpenAI error body. `code` is the B3OS error code; `x-request-id` carries the request ID.

  - Required fields: ` error `

  - ` error `: type ` object `

    - Required fields: ` message `, ` type `, ` param `, ` code `

    - ` message `: type ` string `

    - ` type `: type ` string ` — `invalid_request_error`, `authentication_error`, `permission_error`, `rate_limit_error` or `server_error`.

    - ` param `: type ` string `; nullable

    - ` code `: type ` string `; nullable

Response header ` x-request-id ` — The request ID (`req_…`). It is the `instance` of any problem and the key for `GET /v1/requests/{request_id}`.

- ` value `: type ` string `

  - pattern: ` "^req_[0-9a-hjkmnp-tv-z]{26}$" `

Response header ` Server-Timing ` — Phase durations in milliseconds (W3C Server Timing); the handler's phases break the request down. For a
response whose body size is known, `total` runs from reading the request head to writing the response head.
Streaming responses (event streams, WebSockets, chunked bodies) carry no `total` here: they report their
final phases in the terminal event (`job.succeeded`, `job.failed`, `job.canceled`) or the final job. The
time from the first request byte to the last response byte is recorded in the node's metrics and request
log (`GET /v1/requests/{request_id}`). The edge prepends `edge_auth` and `edge_upstream`.


- ` value `: type ` string `

Response header ` Retry-After ` — Seconds to wait before retrying or polling again.

- ` value `: type ` integer `

  - minimum: ` 0 `

Example:

```json
{
  "error": {
    "message": "The model runtime on n1 is restarting; retry in 5 seconds",
    "type": "server_error",
    "param": null,
    "code": "infer_backend_unavailable"
  }
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/infer/chat/completions' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "string",
  "messages": [
    {
      "role": "system",
      "content": "string",
      "name": "string",
      "tool_calls": [
        {
          "id": "string",
          "type": "function",
          "function": {
            "name": "string",
            "arguments": "string"
          }
        }
      ],
      "tool_call_id": "string",
      "refusal": "string",
      "reasoning_content": "string"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "string",
        "description": "string",
        "parameters": {},
        "strict": true
      }
    }
  ],
  "tool_choice": "none",
  "parallel_tool_calls": true,
  "response_format": {
    "type": "text"
  },
  "temperature": 0,
  "top_p": 0,
  "max_tokens": 1,
  "max_completion_tokens": 1,
  "stop": "string",
  "seed": 0,
  "n": 1,
  "presence_penalty": -2,
  "frequency_penalty": -2,
  "logprobs": true,
  "top_logprobs": 0,
  "user": "string",
  "stream": false,
  "stream_options": {
    "include_usage": true
  },
  "route": "local",
  "top_k": -1,
  "min_p": 0,
  "repetition_penalty": 0,
  "logit_bias": {},
  "chat_template_kwargs": {
    "enable_thinking": true
  },
  "metadata": {},
  "store": true,
  "service_tier": "string"
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/infer/chat/completions', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "model": "string",
    "messages": [
      {
        "role": "system",
        "content": "string",
        "name": "string",
        "tool_calls": [
          {
            "id": "string",
            "type": "function",
            "function": {
              "name": "string",
              "arguments": "string"
            }
          }
        ],
        "tool_call_id": "string",
        "refusal": "string",
        "reasoning_content": "string"
      }
    ],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "string",
          "description": "string",
          "parameters": {},
          "strict": true
        }
      }
    ],
    "tool_choice": "none",
    "parallel_tool_calls": true,
    "response_format": {
      "type": "text"
    },
    "temperature": 0,
    "top_p": 0,
    "max_tokens": 1,
    "max_completion_tokens": 1,
    "stop": "string",
    "seed": 0,
    "n": 1,
    "presence_penalty": -2,
    "frequency_penalty": -2,
    "logprobs": true,
    "top_logprobs": 0,
    "user": "string",
    "stream": false,
    "stream_options": {
      "include_usage": true
    },
    "route": "local",
    "top_k": -1,
    "min_p": 0,
    "repetition_penalty": 0,
    "logit_bias": {},
    "chat_template_kwargs": {
      "enable_thinking": true
    },
    "metadata": {},
    "store": true,
    "service_tier": "string"
  })
});

const data = await response.json();
console.log(data);
```

### Python

```python
import requests

headers = {
    'Authorization': 'Bearer YOUR_API_TOKEN'
}

response = requests.post('https://beta-api.b3os.org/v1/infer/chat/completions', headers=headers, json={
  "model": "string",
  "messages": [
    {
      "role": "system",
      "content": "string",
      "name": "string",
      "tool_calls": [
        {
          "id": "string",
          "type": "function",
          "function": {
            "name": "string",
            "arguments": "string"
          }
        }
      ],
      "tool_call_id": "string",
      "refusal": "string",
      "reasoning_content": "string"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "string",
        "description": "string",
        "parameters": {},
        "strict": true
      }
    }
  ],
  "tool_choice": "none",
  "parallel_tool_calls": true,
  "response_format": {
    "type": "text"
  },
  "temperature": 0,
  "top_p": 0,
  "max_tokens": 1,
  "max_completion_tokens": 1,
  "stop": "string",
  "seed": 0,
  "n": 1,
  "presence_penalty": -2,
  "frequency_penalty": -2,
  "logprobs": true,
  "top_logprobs": 0,
  "user": "string",
  "stream": false,
  "stream_options": {
    "include_usage": true
  },
  "route": "local",
  "top_k": -1,
  "min_p": 0,
  "repetition_penalty": 0,
  "logit_bias": {},
  "chat_template_kwargs": {
    "enable_thinking": true
  },
  "metadata": {},
  "store": true,
  "service_tier": "string"
})
print(response.json())
```