Count message tokens
POST https://api-staging.impossiblecarrot.cc/api/v1/messages/count_tokens
Estimate the input size of a Messages conversation without generating a reply.
Coding clients can use this estimate to decide when to compact their conversation. Requires
Heimdallm bearer authentication: Authorization: Bearer or x-api-key
carrying a Heimdallm API key.
Request body
| Field | Type | Notes |
|---|---|---|
model | string | Required, nonempty marketplace model id. The estimator does not load that model's tokenizer. |
messages | object[] | Required, at least one turn in the Messages shape. |
system | string or object[] | Optional system text or text blocks. |
tools | object[] | Optional definitions with name, description and input_schema. |
No max_tokens is required. Use the same conversation and tool definitions you intend to send
to Messages.
Example
curl https://api-staging.impossiblecarrot.cc/api/v1/messages/count_tokens \
-H "Authorization: Bearer $HEIMDALL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-flash-0731-abliterated",
"messages": [{ "role": "user", "content": "Hello." }]
}'
{ "input_tokens": 11 }
The reply is one JSON object. It has no generation id, output tokens or cost fields. Authentication and validation errors use the public API's HTTP error envelope.
How to use the estimate
The figure is the same estimate the router sizes a Messages request at when it picks an endpoint and
fits the reply's max_tokens to the endpoint's context window. The conversation is translated to the
chat shape first, and each part is then counted by the rule that fits it:
- Prose and code: four characters a token, counting the message structure around them.
- Chinese, Japanese, Korean, Thai, Devanagari and Arabic text: per character, at 1.1 to 2.5 characters a token by script.
- Base64 inside text, such as bytes a tool wrote into its text result: 1.3 characters a token.
- Tool definitions: by the pieces a tokenizer splits their JSON into, plus 200 tokens for the template around them.
- An image block: a fixed 1,600 tokens.
The estimate reads a little high on purpose. Measured against one marketplace model, it came to between 97% and 133% of the real count. It does not contact an inference provider, load the model's tokenizer or verify model availability.
This is not a model tokenizer or a measured usage record. Do not treat it as an exact context-window fit or use it to calculate a charge. The generation reply and account records are separate from this estimate.
Streaming
This route returns JSON only. There is no event stream; stream is not a counting option.
To generate and stream the reply, send a separate Messages request.
See coding harnesses for the related Messages and Responses references.