> ## 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.

# Count the tokens of a message request

The Anthropic token-counting API: the input tokens a Messages request with the same `messages`, `system`, `tools`, `tool_choice` and `thinking` would use, counted by the model runtime with the model's own chat template (images included). Free: it counts against your requests per minute, not your tokens. 

` POST /v1/infer/v1/messages/count_tokens `

Count the tokens of a message request

The Anthropic token-counting API: the input tokens a Messages request with the same `messages`, `system`,
`tools`, `tool_choice` and `thinking` would use, counted by the model runtime with the model's own chat
template (images included). Free: it counts against your requests per minute, not your tokens.


## 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 ` — The input of a Messages request. Any other parameter is `400 unsupported_parameter`.

  - Required fields: ` model `, ` messages `

  - ` model `: type ` string `

    - minLength: ` 1 `

    - maxLength: ` 256 `

  - ` messages `: type ` array `

    - ` array item `: type ` unknown `

      - ` oneOf alternative 1 `: type ` object `

        - Required fields: ` role `, ` content `

        - ` role `: type ` string `

          - enum: ` ["user"] `

        - ` content `: type ` unknown `

          - ` oneOf alternative 1 `: type ` string `

          - ` 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 `

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

                  - ` type `: type ` string `

                  - ` ttl `: type ` string `

                - ` citations `: type ` array `; nullable — Accepted and ignored.

                  - ` array item `: type ` object `

              - ` oneOf alternative 2 `: type ` object `

                - Required fields: ` type `, ` source `

                - ` type `: type ` string `

                  - enum: ` ["image"] `

                - ` source `: type ` unknown `

                  - ` oneOf alternative 1 `: type ` object `

                    - Required fields: ` type `, ` media_type `, ` data `

                    - ` type `: type ` string `

                      - enum: ` ["base64"] `

                    - ` media_type `: type ` string `

                      - enum: ` ["image/png","image/jpeg","image/webp","image/gif"] `

                    - ` data `: type ` string `; format ` byte ` — The image file, which must be a PNG, JPEG, WebP or GIF.

                  - ` oneOf alternative 2 `: type ` object `

                    - Required fields: ` type `, ` url `

                    - ` type `: type ` string `

                      - enum: ` ["url"] `

                    - ` url `: type ` string ` — Fetched by the node through its egress guard (PNG, JPEG, WebP or GIF, at most 10 MiB).

                      - pattern: ` "^https://" `

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

                  - ` type `: type ` string `

                  - ` ttl `: type ` string `

              - ` oneOf alternative 3 `: type ` object `

                - Required fields: ` type `, ` tool_use_id `

                - ` type `: type ` string `

                  - enum: ` ["tool_result"] `

                - ` tool_use_id `: type ` string `

                - ` 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 `

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

                          - ` type `: type ` string `

                          - ` ttl `: type ` string `

                        - ` citations `: type ` array `; nullable — Accepted and ignored.

                          - ` array item `: type ` object `

                      - ` oneOf alternative 2 `: type ` object `

                        - Required fields: ` type `, ` source `

                        - ` type `: type ` string `

                          - enum: ` ["image"] `

                        - ` source `: type ` unknown `

                          - ` oneOf alternative 1 `: type ` object `

                            - Required fields: ` type `, ` media_type `, ` data `

                            - ` type `: type ` string `

                              - enum: ` ["base64"] `

                            - ` media_type `: type ` string `

                              - enum: ` ["image/png","image/jpeg","image/webp","image/gif"] `

                            - ` data `: type ` string `; format ` byte ` — The image file, which must be a PNG, JPEG, WebP or GIF.

                          - ` oneOf alternative 2 `: type ` object `

                            - Required fields: ` type `, ` url `

                            - ` type `: type ` string `

                              - enum: ` ["url"] `

                            - ` url `: type ` string ` — Fetched by the node through its egress guard (PNG, JPEG, WebP or GIF, at most 10 MiB).

                              - pattern: ` "^https://" `

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

                          - ` type `: type ` string `

                          - ` ttl `: type ` string `

                - ` is_error `: type ` boolean `; nullable — The result is an error; the model sees it prefixed with `Error:`.

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

                  - ` type `: type ` string `

                  - ` ttl `: type ` string `

      - ` oneOf alternative 2 `: type ` object ` — An earlier answer; as the last message, the start of the answer, which the model continues.

        - Required fields: ` role `, ` content `

        - ` role `: type ` string `

          - enum: ` ["assistant"] `

        - ` content `: type ` unknown `

          - ` oneOf alternative 1 `: type ` string `

          - ` 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 `

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

                  - ` type `: type ` string `

                  - ` ttl `: type ` string `

                - ` citations `: type ` array `; nullable — Accepted and ignored.

                  - ` array item `: type ` object `

              - ` oneOf alternative 2 `: type ` object `

                - Required fields: ` type `, ` id `, ` name `, ` input `

                - ` type `: type ` string `

                  - enum: ` ["tool_use"] `

                - ` id `: type ` string `

                  - minLength: ` 1 `

                - ` name `: type ` string `

                - ` input `: type ` object `

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

                  - ` type `: type ` string `

                  - ` ttl `: type ` string `

              - ` oneOf alternative 3 `: type ` object `

                - Required fields: ` type `, ` thinking `

                - ` type `: type ` string `

                  - enum: ` ["thinking"] `

                - ` thinking `: type ` string `

                - ` signature `: type ` string `; nullable — Opaque; this node does not check it.

              - ` oneOf alternative 4 `: type ` object ` — Accepted in assistant turns and left out of the prompt.

                - Required fields: ` type `, ` data `

                - ` type `: type ` string `

                  - enum: ` ["redacted_thinking"] `

                - ` data `: type ` string `

  - ` system `: type ` unknown ` — The system prompt; text blocks are joined with blank lines.

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

    - ` oneOf alternative 2 `: type ` array `

      - ` array item `: type ` object `

        - Required fields: ` type `, ` text `

        - ` type `: type ` string `

          - enum: ` ["text"] `

        - ` text `: type ` string `

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

          - ` type `: type ` string `

          - ` ttl `: type ` string `

        - ` citations `: type ` array `; nullable — Accepted and ignored.

          - ` array item `: type ` object `

  - ` tools `: type ` array `; nullable

    - ` array item `: type ` object ` — A custom tool. Tools Anthropic defines or runs (a `type` other than `custom`) are `unsupported_parameter`.

      - Required fields: ` name `, ` input_schema `

      - ` type `: type ` string `; nullable

        - enum: ` ["custom",null] `

      - ` name `: type ` string ` — Unique within `tools`.

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

      - ` description `: type ` string `; nullable

      - ` input_schema `: type ` object ` — A JSON Schema object (at most 64 KiB serialized and 32 levels deep).

      - ` strict `: type ` boolean `; nullable

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

        - ` type `: type ` string `

        - ` ttl `: type ` string `

  - ` tool_choice `: type ` object `; nullable

    - ` oneOf alternative 1 `: type ` object `

      - Required fields: ` type `

      - ` type `: type ` string ` — `any` makes the model call a tool (it needs `tools`).

        - enum: ` ["auto","any"] `

      - ` disable_parallel_tool_use `: type ` boolean `; nullable

    - ` oneOf alternative 2 `: type ` object `

      - Required fields: ` type `, ` name `

      - ` type `: type ` string `

        - enum: ` ["tool"] `

      - ` name `: type ` string ` — One of `tools`.

      - ` disable_parallel_tool_use `: type ` boolean `; nullable

    - ` oneOf alternative 3 `: type ` object `

      - Required fields: ` type `

      - ` type `: type ` string `

        - enum: ` ["none"] `

  - ` thinking `: type ` object `; nullable — `enabled` (with `budget_tokens`, at least 1024 and less than `max_tokens`) and `adaptive` let the model reason first, in `thinking` blocks; `disabled`, the default, does not. `display` is accepted and ignored. 

    - ` oneOf alternative 1 `: type ` object `

      - Required fields: ` type `, ` budget_tokens `

      - ` type `: type ` string `

        - enum: ` ["enabled"] `

      - ` budget_tokens `: type ` integer `

        - minimum: ` 1024 `

      - ` display `: type ` string `; nullable

        - enum: ` ["summarized","omitted","updates",null] `

    - ` oneOf alternative 2 `: type ` object `

      - Required fields: ` type `

      - ` type `: type ` string `

        - enum: ` ["adaptive"] `

      - ` display `: type ` string `; nullable

        - enum: ` ["summarized","omitted","updates",null] `

    - ` oneOf alternative 3 `: type ` object `

      - Required fields: ` type `

      - ` type `: type ` string `

        - enum: ` ["disabled"] `

Example:

```json
{
  "model": "b3os/qwen3.5-9b",
  "system": "You are a concise assistant.",
  "messages": [
    {
      "role": "user",
      "content": "How many tokens is this?"
    }
  ]
}
```

## Responses

### ` 200 ` — The count.

Content type: ` application/json `

- ` value `: type ` object `

  - Required fields: ` input_tokens `

  - ` input_tokens `: type ` integer `

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 ` request-id ` — The request ID under the name Anthropic SDKs read (`_request_id`); `x-request-id` carries it too.

- ` value `: type ` string `

Example:

```json
{
  "input_tokens": 27
}
```

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

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "web_search_20250305 is a tool Anthropic defines or runs; this node takes custom tools (name, description, input_schema)"
  },
  "request_id": "req_01m5t4yg394wegr3j4y01qb363",
  "b3os": {
    "code": "unsupported_parameter",
    "param": "tools.0.type"
  }
}
```

### ` 401 ` — Missing or invalid credentials (`unauthorized`), checked before the request reaches the infer service (OpenAI shape).

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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` (`forbidden`, OpenAI shape), or the egress guard refused an image URL (`egress_denied`).

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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 ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "claude-sonnet-4-5 is not served on this node; GET /v1/infer/models lists the models that are"
  },
  "b3os": {
    "code": "model_not_available",
    "param": "model"
  }
}
```

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

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "request_too_large",
    "message": "Request body is 12582912 bytes; b3os/qwen3.5-9b accepts at most 10485760"
  },
  "b3os": {
    "code": "payload_too_large"
  }
}
```

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

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "expected Content-Type: application/json"
  },
  "b3os": {
    "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).

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "message": "200000 tokens per minute allowed on b3os/qwen3.5-9b; retry in 9 seconds"
  },
  "b3os": {
    "code": "rate_limited"
  }
}
```

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

Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "api_error",
    "message": "internal error (request req_01m5t4yg394wegr3j4y01qb363)"
  },
  "b3os": {
    "code": "internal"
  }
}
```

### ` 503 ` — The model runtime is restarting, overloaded or not set up on this node (`infer_backend_unavailable`), or
the node is unavailable (`node_unavailable`, OpenAI shape).


Content type: ` application/json `

- ` value `: type ` unknown ` — The Anthropic error body, or the OpenAI one for errors raised before the request reaches the infer service.

  - ` oneOf alternative 1 `: type ` object ` — The Anthropic error body, with the B3OS code and the offending parameter (a dotted path) under `b3os`.

    - Required fields: ` type `, ` error `

    - ` type `: type ` string `

      - enum: ` ["error"] `

    - ` error `: type ` object `

      - Required fields: ` type `, ` message `

      - ` type `: type ` string `

        - enum: ` ["invalid_request_error","authentication_error","billing_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","timeout_error","overloaded_error"] `

      - ` message `: type ` string `

    - ` request_id `: type ` string `

    - ` b3os `: type ` object `

      - Required fields: ` code `

      - ` code `: type ` string `

      - ` param `: type ` string `

  - ` oneOf alternative 2 `: 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
{
  "type": "error",
  "error": {
    "type": "overloaded_error",
    "message": "The model runtime on n1 is restarting; retry in 5 seconds"
  },
  "b3os": {
    "code": "infer_backend_unavailable"
  }
}
```

## Request examples

### cURL

```curl
curl -X POST 'https://beta-api.b3os.org/v1/infer/v1/messages/count_tokens' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "b3os/qwen3.5-9b",
  "system": "You are a concise assistant.",
  "messages": [
    {
      "role": "user",
      "content": "How many tokens is this?"
    }
  ]
}'
```

### JavaScript

```javascript
const response = await fetch('https://beta-api.b3os.org/v1/infer/v1/messages/count_tokens', {
  method: 'POST',
  headers: {
      "Authorization": "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "model": "b3os/qwen3.5-9b",
    "system": "You are a concise assistant.",
    "messages": [
      {
        "role": "user",
        "content": "How many tokens is this?"
      }
    ]
  })
});

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/v1/messages/count_tokens', headers=headers, json={
  "model": "b3os/qwen3.5-9b",
  "system": "You are a concise assistant.",
  "messages": [
    {
      "role": "user",
      "content": "How many tokens is this?"
    }
  ]
})
print(response.json())
```