POST /v1/infer/v1/messages/count_tokens
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.

Authentication

Bearer Token (b3os_sk_ API key or b3os_pat_ token) API Key (cookie: __Host-b3os_session)

Request Body required

application/json
model string REQUIRED
messages (object | object)[] REQUIRED
Array of:
One of:
Option 1
role string REQUIRED
Enum: user
content string | (object | object | object)[] REQUIRED
One of:
Option 1string
Option 2
Array of:
One of:
Option 1...
Option 2...
Option 3...
Option 2
role string REQUIRED
Enum: assistant
content string | (object | object | object | object)[] REQUIRED
One of:
Option 1string
Option 2
Array of:
One of:
Option 1...
Option 2...
Option 3...
Option 4...
system string | null | object[]
The system prompt; text blocks are joined with blank lines.
One of:
Option 1string | null
Option 2
Array of:
type string REQUIRED
Enum: text
text string REQUIRED
cache_control object | null
Accepted and ignored.
type string
ttl string
citations object[] | null
Accepted and ignored.
Array of: object
tools object[] | null
Array of:
type string | null
Enum: custom, null
name string REQUIRED
Unique within `tools`.
description string | null
input_schema object REQUIRED
A JSON Schema object (at most 64 KiB serialized and 32 levels deep).
strict boolean | null
cache_control object | null
Accepted and ignored.
type string
ttl string
tool_choice object | object | object | null
One of:
Option 1
type string REQUIRED
`any` makes the model call a tool (it needs `tools`).
Enum: auto, any
disable_parallel_tool_use boolean | null
Option 2
type string REQUIRED
Enum: tool
name string REQUIRED
One of `tools`.
disable_parallel_tool_use boolean | null
Option 3
type string REQUIRED
Enum: none
thinking object | object | object | null
`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.
One of:
Option 1
type string REQUIRED
Enum: enabled
budget_tokens integer REQUIRED
display string | null
Enum: summarized, omitted, updates, null
Option 2
type string REQUIRED
Enum: adaptive
display string | null
Enum: summarized, omitted, updates, null
Option 3
type string REQUIRED
Enum: disabled

Responses

200 The count.
application/json
input_tokens integer REQUIRED
400 The request is invalid (`invalid_request`, `unsupported_parameter`, `context_length_exceeded`, `unsupported_media_type`).
401 Missing or invalid credentials (`unauthorized`), checked before the request reaches the infer service (OpenAI shape).
403 The key lacks `infer:run` (`forbidden`, OpenAI shape), or the egress guard refused an image URL (`egress_denied`).
404 The model is not served on this node (`model_not_available`).
413 The request body exceeds the model's `max_request_bytes` (`payload_too_large`).
415 The body is not JSON (`unsupported_media_type`): send `Content-Type: application/json`.
429 A limit applies (`rate_limited` for requests, tokens or remote image bytes per minute, `concurrency_limited` for requests in flight for the organization).
500 Something failed inside B3OS (`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).
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?"    }  ]}'
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);
import requestsheaders = {    '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())
200 Response
{  "input_tokens": 27}
Ask a question... ⌘I