---
title: "Count tokens API · check prompt size before you send it"
description: "Count the input tokens of a Messages request before you send it. Anthropic-compatible count_tokens endpoint on inference.eu, processed in the EU."
canonical: "https://inference.eu/api/count-tokens/"
language: "en"
---

POST /v1/messages/count\_tokens

# Count tokens API: measure a prompt before you send it

The count tokens endpoint tells you how many input tokens a request would use, without running the model. It takes the same body as a Messages request and returns a single number. Use it to check that long documents fit the context window, to split work into batches of the right size, and to estimate spend before a large job.

[Contact sales](https://inference.eu/contact/)[Example request](#example)

1.  01API format: Anthropic Messages
2.  02EU data centres
3.  03Covered by one DPA

POST /v1/messages/count\_tokens

```
curl https://api.inference.eu/v1/messages/count_tokens \
  -H "x-api-key: $INFERENCE_EU_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-120b",
    "system": "You summarise supplier contracts for a procurement team.",
    "messages": [
      {"role": "user", "content": "Summarise the termination and liability clauses in the contract below.\n\n..."}
    ]
  }'

# {"input_tokens": 2147}
```

## What the endpoint does

`POST /v1/messages/count_tokens` follows the Anthropic token counting format. You send `model`, `messages` and, if you use them, `system` and `tools`. The API tokenises everything exactly as it would for a real request, using the tokenizer of the model you name, and returns `{"input_tokens": N}`.

Nothing is generated and no output tokens are produced, so the call is fast and you do not need `max_tokens`. The count includes the system prompt, every message, tool definitions and the formatting the model's chat template adds around them, which is why it is more accurate than counting words or running a generic tokenizer yourself.

## Why the tokenizer matters

Different open models split text into tokens in different ways. The same contract can be noticeably more tokens for one model than another, especially for German, French and other non-English text, code, or tables. Context windows and token-based billing are both counted in the tokens of the specific model.

That is why the `model` field is required and why you should count with the model you will actually call. If you switch models, recount. A rough rule of thumb from one tokenizer can be wrong by enough to push a long prompt over the limit, and the API will then reject the request with a 400 error.

## A practical pattern for long documents

Before sending a long document, count the tokens of your system prompt, the document and the question together. If the total plus the answer you expect fits within the model's context window, send it as one request. If not, split the document into chunks that each fit, summarise or extract from each chunk, and combine the results in a final call.

The same check is useful for batch jobs. Count a sample of inputs, multiply by the number of rows, and you have a realistic estimate of input volume before you submit the batch, instead of finding out from the invoice.

## Errors and edge cases

Errors use the Anthropic format. An unknown `model` returns `not_found_error` (404); malformed `messages`, for example two `user` turns in a row where the model's template does not allow it, return `invalid_request_error` (400). A bad key returns 401.

The count covers input only. Output tokens, including reasoning on thinking models, are added when the model generates, so leave room for them. Images in content blocks are counted according to the vision model's own rules, which depend on resolution. Counts reflect the current tokenizer and template for each model, so do not cache them across model versions.

## Count tokens

Endpoint

POST /v1/messages/count\_tokens

Category

Endpoints

API format

Anthropic Messages

Base URL

api.inference.eu/v1

Processing

EU data centres

Training on your data

Never

## Count tokens: common questions

The questions buyers, developers and legal teams ask us most. Something missing? Ask us directly.

Send the request body you plan to use, without \`max\_tokens\`, to \`POST /v1/messages/count\_tokens\`. The response contains \`input\_tokens\`, the exact number the model would read. Compare it with the model's context window, leaving room for the answer, before you send the real request.

Yes. The path, headers, request body and response follow Anthropic's count tokens endpoint, so the Anthropic SDK method \`messages.count\_tokens\` works when the client points at inference.eu. The difference is that the count uses the tokenizer of the open model you name.

Counting does not run the model and produces no output. How count requests are treated on your invoice depends on your plan, and we confirm it with you when you sign up. Count calls can be subject to rate limits like any other request.

Each model family has its own tokenizer and chat template. Some split German compound words or code into more pieces than others, and templates add different control tokens around messages. Always count with the model you will call, and recount after switching.

Yes. Tool names, descriptions and JSON schemas are added to the prompt the model sees, so they use input tokens on every request. Include your \`tools\` array in the count request to get a realistic number. Long descriptions on many tools add up quickly.

The count tokens endpoint uses the Anthropic body. For OpenAI-format requests, put your system prompt in \`system\` and the rest in \`messages\`; the count is the same because the model and tokenizer are the same. After a real call, the \`usage\` object reports exact \`prompt\_tokens\`.

Yes, when you include image blocks and name a vision model. Image tokens depend on resolution and on how that model splits images into tiles, so large images can use far more tokens than you expect. Resize images to the detail the task needs before sending them.

No. Content sent for counting is tokenised in EU data centres to return the number and is not kept for any other purpose. It is never used to train models, the same as every other request to the inference.eu API.

[Ask a question](https://inference.eu/contact/)

## Related

[API overview](https://inference.eu/api/)

-   [Messages (Anthropic format)Call open-weight models with the Anthropic Messages format on inference.eu. Works with Anthropic SDKs and Claude Code, processed in EU data centres.Endpoints](https://inference.eu/api/messages/)
-   [Prompt cachingReuse the processed start of a prompt across requests with automatic prompt caching. Structure prompts for cache hits and read cached\_tokens in usage.Guides](https://inference.eu/api/prompt-caching/)
-   [BatchesRun thousands of chat or embedding requests as one asynchronous job with an OpenAI-compatible batch API. Upload JSONL, collect results, all in the EU.Endpoints](https://inference.eu/api/batches/)
-   [Rate limits and errorsHow rate limits and errors work on the inference.eu API. HTTP status codes, the error object, rate-limit headers and a retry pattern that holds up.Guides](https://inference.eu/api/rate-limits-and-errors/)

## Move your AI workloads to EU infrastructure

Tell us which models you use and roughly how much traffic you have. We reply within one working day with pricing and next steps.

-   Reply within one working day
-   Pricing for your volume
-   DPA ready to sign
