curl --request POST \
--url https://api.mixroute.ai/v1/messages/count_tokens \
--header 'Authorization: Bearer sk-xxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
from anthropic import Anthropic
client = Anthropic(
api_key="sk-xxxxxxxxxx",
base_url="https://api.mixroute.ai"
)
response = client.messages.count_tokens(
model="claude-opus-4-8",
messages=[
{"role": "user", "content": "Hello, how are you?"}
]
)
print(f"Input tokens: {response.input_tokens}")
const response = await fetch('https://api.mixroute.ai/v1/messages/count_tokens', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
})
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->post('https://api.mixroute.ai/v1/messages/count_tokens', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx',
'Content-Type' => 'application/json',
],
'json' => [
'model' => 'claude-opus-4-8',
'messages' => [
['role' => 'user', 'content' => 'Hello, how are you?']
]
]
]);
echo $response->getBody();
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "claude-opus-4-8",
"messages": []map[string]string{
{"role": "user", "content": "Hello, how are you?"},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.mixroute.ai/v1/messages/count_tokens", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/messages/count_tokens"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/messages/count_tokens')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
request['Content-Type'] = 'application/json'
request.body = {
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
}.to_json
response = http.request(request)
puts response.body
{
"input_tokens": 14
}
Text Series
Count Tokens (Claude)
Calculate Claude message token count for cost estimation before sending requests
POST
/
v1
/
messages
/
count_tokens
curl --request POST \
--url https://api.mixroute.ai/v1/messages/count_tokens \
--header 'Authorization: Bearer sk-xxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
from anthropic import Anthropic
client = Anthropic(
api_key="sk-xxxxxxxxxx",
base_url="https://api.mixroute.ai"
)
response = client.messages.count_tokens(
model="claude-opus-4-8",
messages=[
{"role": "user", "content": "Hello, how are you?"}
]
)
print(f"Input tokens: {response.input_tokens}")
const response = await fetch('https://api.mixroute.ai/v1/messages/count_tokens', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
})
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->post('https://api.mixroute.ai/v1/messages/count_tokens', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx',
'Content-Type' => 'application/json',
],
'json' => [
'model' => 'claude-opus-4-8',
'messages' => [
['role' => 'user', 'content' => 'Hello, how are you?']
]
]
]);
echo $response->getBody();
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "claude-opus-4-8",
"messages": []map[string]string{
{"role": "user", "content": "Hello, how are you?"},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.mixroute.ai/v1/messages/count_tokens", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/messages/count_tokens"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/messages/count_tokens')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
request['Content-Type'] = 'application/json'
request.body = {
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
}.to_json
response = http.request(request)
puts response.body
{
"input_tokens": 14
}
Introduction
Calculate the token count for Claude messages, used for cost estimation before sending requests. This endpoint does not consume quota, only performs local calculation.Authentication
Bearer Token, e.g.,Bearer sk-xxxxxxxxxx
Request Parameters
string
required
Claude model identifier, supported models include:
claude-opus-4-8claude-sonnet-5claude-haiku-4-5- Other Claude series models
array
required
Conversation messages list, each element contains
role (user/assistant) and content. content can be a string or media content array.Supported content types:- Plain text messages
- Multimodal messages (with images)
- Tool call results
string
System prompt (optional), can be a string or media content array. Used to set model behavior and role.
array
Tool definition list (optional), used to calculate tool call related token count.
Response Parameters
integer
Total token count of input messages, including:
- All messages token count
- System prompt token count
- Tools definition token count (if any)
Basic Examples
- Simple Text Message
- With System Prompt
- Multi-turn Conversation
curl -X POST "https://api.mixroute.ai/v1/messages/count_tokens" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": "Hello, how are you?"
}
]
}'
curl -X POST "https://api.mixroute.ai/v1/messages/count_tokens" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-d '{
"model": "claude-opus-4-8",
"system": "You are a helpful AI assistant.",
"messages": [
{
"role": "user",
"content": "What is artificial intelligence?"
}
]
}'
curl -X POST "https://api.mixroute.ai/v1/messages/count_tokens" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": "Hello"
},
{
"role": "assistant",
"content": "Hello! How can I help you?"
},
{
"role": "user",
"content": "Tell me about the history of artificial intelligence"
}
]
}'
Python Example
from anthropic import Anthropic
client = Anthropic(
api_key="sk-xxxxxxxxxx",
base_url="https://api.mixroute.ai"
)
# Count tokens
response = client.messages.count_tokens(
model="claude-opus-4-8",
system="You are a helpful assistant.",
messages=[
{"role": "user", "content": "Hello, Claude!"}
]
)
print(f"Input tokens: {response.input_tokens}")
Response Example
{
"input_tokens": 14
}
Advanced Use Cases
- With Tool Definitions
- Multimodal Content
curl -X POST "https://api.mixroute.ai/v1/messages/count_tokens" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": "What is the weather in San Francisco?"
}
],
"tools": [
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
}
},
"required": ["location"]
}
}
]
}'
curl -X POST "https://api.mixroute.ai/v1/messages/count_tokens" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is in this image?"
},
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/image.jpg"
}
}
]
}
]
}'
Use Cases
1. Cost Estimation
Calculate token count before sending bulk requests to estimate costs:# Batch cost calculation
messages_batch = [...] # Batch messages
total_tokens = 0
for messages in messages_batch:
response = client.messages.count_tokens(
model="claude-opus-4-8",
messages=messages
)
total_tokens += response.input_tokens
# Calculate total cost based on pricing
cost = total_tokens * price_per_token
print(f"Estimated cost: ${cost:.4f}")
2. Context Window Management
Check if messages exceed the model’s context window limit:MAX_CONTEXT_WINDOW = 1000000 # Claude Sonnet 5 context window
response = client.messages.count_tokens(
model="claude-opus-4-8",
messages=long_conversation
)
if response.input_tokens > MAX_CONTEXT_WINDOW:
print(f"Warning: Message token count ({response.input_tokens}) exceeds context window limit")
# Execute message truncation or summarization
3. Prompt Optimization
Compare token consumption of different prompts:prompts = [
"Concise prompt...",
"Detailed prompt...",
"Very detailed prompt..."
]
for prompt in prompts:
response = client.messages.count_tokens(
model="claude-opus-4-8",
system=prompt,
messages=[{"role": "user", "content": "Test"}]
)
print(f"{len(prompt)} characters -> {response.input_tokens} tokens")
Notes
- This endpoint does not make actual AI requests, does not consume quota
- Does not include output-related parameters like
max_tokens, only calculates input token count - Image tokens use fixed estimates (approx 1000 tokens), actual may vary based on resolution
Error Handling
Missing Required Parameters
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "Key: 'ClaudeCountTokensRequest.Model' Error:Field validation for 'Model' failed on the 'required' tag"
}
}
Invalid API Key
{
"error": {
"message": "Invalid token",
"type": "invalid_request_error"
}
}
Related Resources
- Pricing - Learn about token billing standards
- Model List - View supported Claude models
- Create Message Request (Claude) - Send actual Claude requests
curl --request POST \
--url https://api.mixroute.ai/v1/messages/count_tokens \
--header 'Authorization: Bearer sk-xxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
from anthropic import Anthropic
client = Anthropic(
api_key="sk-xxxxxxxxxx",
base_url="https://api.mixroute.ai"
)
response = client.messages.count_tokens(
model="claude-opus-4-8",
messages=[
{"role": "user", "content": "Hello, how are you?"}
]
)
print(f"Input tokens: {response.input_tokens}")
const response = await fetch('https://api.mixroute.ai/v1/messages/count_tokens', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk-xxxxxxxxxx',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
})
});
const data = await response.json();
console.log(data);
<?php
$client = new GuzzleHttp\Client();
$response = $client->post('https://api.mixroute.ai/v1/messages/count_tokens', [
'headers' => [
'Authorization' => 'Bearer sk-xxxxxxxxxx',
'Content-Type' => 'application/json',
],
'json' => [
'model' => 'claude-opus-4-8',
'messages' => [
['role' => 'user', 'content' => 'Hello, how are you?']
]
]
]);
echo $response->getBody();
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "claude-opus-4-8",
"messages": []map[string]string{
{"role": "user", "content": "Hello, how are you?"},
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.mixroute.ai/v1/messages/count_tokens", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer sk-xxxxxxxxxx")
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"model": "claude-opus-4-8",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mixroute.ai/v1/messages/count_tokens"))
.header("Authorization", "Bearer sk-xxxxxxxxxx")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
require 'net/http'
require 'json'
uri = URI('https://api.mixroute.ai/v1/messages/count_tokens')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'Bearer sk-xxxxxxxxxx'
request['Content-Type'] = 'application/json'
request.body = {
model: 'claude-opus-4-8',
messages: [
{ role: 'user', content: 'Hello, how are you?' }
]
}.to_json
response = http.request(request)
puts response.body
{
"input_tokens": 14
}
⌘I