The real ways to count tokens — the local libraries that cost nothing and the provider endpoints that know about images, tools and chat scaffolding. The playground on this site uses the first option below; new to the terms? Start with the glossary.
Heads up
Every keyed call below belongs on a server. An API key in browser code is a public API key. This page is documentation — it makes no requests and stores no keys.
The same library the playground on this site uses. Exact counts, no network call, no key, no cost. This is the default answer for token counting.
no endpoint — runs in your process or browser
import { Tiktoken } from "js-tiktoken/lite";
import o200k from "js-tiktoken/ranks/o200k_base";
const enc = new Tiktoken(o200k);
const ids = enc.encode("How many tokens is this?");
ids.length; // 6
enc.decode([ids[0]]); // "How"Every completion returns exactly what you were billed for. This is the ground truth: use it to reconcile, not to plan.
POST https://api.openai.com/v1/chat/completions
curl https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{ "role": "user", "content": "Hello" }],
"max_tokens": 1
}'
# -> "usage": { "prompt_tokens": 8, "completion_tokens": 1, "total_tokens": 9 }A dedicated, free counting endpoint. Claude's tokenizer is not published, so for Claude this endpoint is the only exact option.
POST https://api.anthropic.com/v1/messages/count_tokens
curl https://api.anthropic.com/v1/messages/count_tokens \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{ "role": "user", "content": "Hello" }]
}'
# -> { "input_tokens": 8 }Same idea as Anthropic's: a free counting call that mirrors what generation will bill.
POST https://generativelanguage.googleapis.com/v1beta/models/{model}:countTokens
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:countTokens" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contents": [{ "parts": [{ "text": "Hello" }] }] }'
# -> { "totalTokens": 1 }For open models (Llama, Mistral, Qwen…). Each model ships its own tokenizer.json, which you can load locally in Python or in the browser.
no endpoint — tokenizer.json loaded from the model repo
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.3")
ids = tok.encode("How many tokens is this?")
len(ids) # model-specific
tok.convert_ids_to_tokens(ids)Endpoints and model names change — the linked official docs are always the source of truth.