POST /v1/chat/count_tokens returns the number of input tokens a chat request would use, without running inference. Use it for cost estimates, context-window checks, and validating a request before you queue it.
The count matches the prompt_tokens you would be billed for on the same request to /v1/chat/completions. It accounts for the system prompt, every message, tool definitions, the model's chat template, and the thinking-mode tokens added by reasoning_effort.
curl -s "https://api.privatemind.com/v1/chat/count_tokens" \
-H "Authorization: Bearer $PMIND_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fast",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you today?"}
]
}'
# => { "input_tokens": 23, "context_window": 131072 }import httpx
resp = httpx.post(
"https://api.privatemind.com/v1/chat/count_tokens",
headers={"Authorization": f"Bearer {PMIND_KEY}"},
json={
"model": "fast",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you today?"},
],
},
)
print(resp.json()["input_tokens"])const resp = await fetch('https://api.privatemind.com/v1/chat/count_tokens', {
method: 'POST',
headers: {
Authorization: `Bearer ${PMIND_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'fast',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Hello, how are you today?' },
],
}),
});
const { input_tokens } = await resp.json();
console.log(input_tokens);Parameters
The request takes the token-affecting fields of a chat completion. Sampling parameters (temperature, max_tokens, stream, …) are accepted but ignored: they do not change the input token count.
model(required): id or alias of a chat model, resolved exactly as/v1/chat/completionsresolves it. Unknown models returnmodel_not_found.messages(required): the conversation, same shape as chat completions.tools: tool definitions. Counted for models whose chat template renders tools into the prompt.reasoning_effort:off|low|medium|high. On a thinking model this changes the template and therefore the count, so pass the same value you will send to the completion.
Response
{
"input_tokens": 23,
"context_window": 131072
}input_tokens: input tokens the request would consume, the same number billed asprompt_tokenson the matching completion.context_window: the model's maximum context length in tokens. Compareinput_tokens(plus the completion you expect to generate) against this to detect overflow before you send.
Counting is free: a count_tokens call is never billed and writes no usage.
Cost and context checks
Two common uses:
- Cost estimate. Multiply
input_tokensby the model's input rate (see Usage for per-model rates) to show an estimated cost before sending. - Context-window guard. If
input_tokensalready approachescontext_window, trim or summarise the conversation before calling/v1/chat/completions, rather than letting the model reject an over-long prompt.
Where next
- Chat completions: the endpoint whose
prompt_tokensthis mirrors. - Models: find a model's id, alias, and context window.
- Usage: per-model token rates for turning a count into a cost.
- Rate limits & budgets: how budgets and RPM apply to your keys.