token-counting
build-with-claude/token-counting
History
build-with-claude/token-counting Changed · +1 / -1 lines
### Supported models -All [active models](https://platform.claude.com/docs/en/about-claude/models/overview) support token counting, including Claude Opus 5 and Claude Sonnet 5. +All [active models](https://platform.claude.com/docs/en/models/overview) support token counting, including Claude Opus 5 and Claude Sonnet 5. <Note> Claude 4.7 and later models and Claude Mythos Preview use a newer tokenizer. The same input text produces approximately 30 percent more tokens than on earlier models. The exact increase depends on the content and workload shape. Recount prompts against the model you plan to use rather than reusing counts measured against earlier models.
build-with-claude/token-counting Changed · +4 / -2 lines
```python Python import base64 - import httpx + import httpx2 image_url = "https://platform.claude.com/docs/images/vision-example.jpg" image_media_type = "image/jpeg" - image_data = base64.standard_b64encode(httpx.get(image_url).content).decode("utf-8") + image_data = base64.standard_b64encode(httpx2.get(image_url).content).decode("utf-8") client = anthropic.Anthropic()
```json Output { "input_tokens": 1028 } ``` + +An embedded image block that sets [`"oversized_image": "error"`](https://platform.claude.com/docs/en/build-with-claude/vision-coordinates#oversized-image-error) is rejected at count time exactly as the Messages API would reject it. ### Count tokens in messages with thinking
build-with-claude/token-counting First recorded · 1449 lines, first recorded
## Compatibility ## How to count message tokens ### Supported models ### Count tokens in basic messages ### Count tokens in messages with tools ### Count tokens in messages with images ### Count tokens in messages with thinking ### Count tokens in messages with PDFs ## Token counts on Claude Fable 5 and Claude Mythos 5 ## Pricing and rate limits ## FAQ ## Next steps
The first capture of this source. The page was already there, and this is what it said.
---
title: Token counting
url: https://platform.claude.com/docs/en/build-with-claude/token-counting
description: Count the tokens in a message before you send it to Claude. Use token counts to manage rate limits and costs, make model routing decisions, and fit prompts to a target length.
---
## Compatibility
- [ZDR](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention): eligible (excludes [Covered Models](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#model-specific-data-retention-requirements))
- Platforms: Claude API, Claude Platform on AWS, Amazon Bedrock, Google Cloud, Microsoft Foundry
Token counting lets you determine the number of tokens in a message before you send it to Claude. This helps you make informed decisions about your prompts and usage. With token counting, you can:
* Proactively manage rate limits and costs
* Make smart model routing decisions
* Optimize prompts to a specific length
***
## How to count message tokens
The [token counting](https://platform.claude.com/docs/en/api/messages-count-tokens) endpoint accepts the same structured list of inputs for creating a message, including support for system prompts, [tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview), [images](https://platform.claude.com/docs/en/build-with-claude/vision), and [PDFs](https://platform.claude.com/docs/en/build-with-claude/pdf-support). The response contains the total number of input tokens.
<Note>
The token count is an **estimate**. In some cases, the actual number of input tokens used when creating a message might differ by a small amount.
Token counts may include tokens added automatically by Anthropic for system optimizations. **You are not billed for system-added tokens**. Billing reflects only your content.
</Note>
### Supported models
All [active models](https://platform.claude.com/docs/en/about-claude/models/overview) support token counting, including Claude Opus 5 and Claude Sonnet 5.
<Note>
Claude 4.7 and later models and Claude Mythos Preview use a newer tokenizer. The same input text produces approximately 30 percent more tokens than on earlier models. The exact increase depends on the content and workload shape. Recount prompts against the model you plan to use rather than reusing counts measured against earlier models.
</Note>
### Count tokens in basic messages
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages/count_tokens \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"system": "You are a scientist",
"messages": [{
"role": "user",
"content": "Hello, Claude"
}]
}'
```
```bash CLI
ant messages count-tokens \
--model claude-opus-5 \
--system "You are a scientist" \
--message '{role: user, content: "Hello, Claude"}'
```
```python Python
client = anthropic.Anthropic()
response = client.messages.count_tokens(
model="claude-opus-5",
system="You are a scientist",
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(response.json())
```
```typescript TypeScript
const client = new Anthropic();
const response = await client.messages.countTokens({
model: "claude-opus-5",
system: "You are a scientist",
messages: [
{
role: "user",
content: "Hello, Claude"
}
]
});
console.log(response);
```
```csharp C#
using System;
using System.Threading.Tasks;
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCountTokensParams
{
Model = Model.ClaudeOpus5,
System = "You are a scientist",
Messages = [new() { Role = Role.User, Content = "Hello, Claude" }]
};
var response = await client.Messages.CountTokens(parameters);
Console.WriteLine(response);
```
```go Go
client := anthropic.NewClient()
response, err := client.Messages.CountTokens(context.TODO(), anthropic.MessageCountTokensParams{
Model: anthropic.ModelClaudeOpus5,
System: anthropic.MessageCountTokensParamsSystemUnion{
OfString: anthropic.String("You are a scientist"),
},
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response)
```
```java Java
import com.anthropic.models.messages.MessageCountTokensParams;
import com.anthropic.models.messages.MessageTokensCount;
// ...
public class CountTokensExample {
public static void main(String[] args) {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCountTokensParams params = MessageCountTokensParams.builder()
.model(Model.CLAUDE_OPUS_5)
.system("You are a scientist")
.addUserMessage("Hello, Claude")
.build();
MessageTokensCount count = client.messages().countTokens(params);
System.out.println(count);
}
}
```
```php PHP
$client = new Client();
$response = $client->messages->countTokens(
messages: [
['role' => 'user', 'content' => 'Hello, Claude']
],
model: 'claude-opus-5',
system: 'You are a scientist',
);
echo json_encode($response);
```
```ruby Ruby
client = Anthropic::Client.new
response = client.messages.count_tokens(
model: "claude-opus-5",
system: "You are a scientist",
messages: [
{ role: "user", content: "Hello, Claude" }
]
)
puts response
```
</CodeGroup>
```json Output
{ "input_tokens": 14 }
```
### Count tokens in messages with tools
<Note>
[Server tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools) token counts only apply to the first sampling call.
</Note>
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages/count_tokens \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"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"]
}
}
],
"messages": [
{
"role": "user",
"content": "What'\''s the weather like in San Francisco?"
}
]
}'
```
```bash CLI
ant messages count-tokens <<'YAML'
model: claude-opus-5
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
messages:
- role: user
content: What's the weather like in San Francisco?
YAML
```
```python Python
client = anthropic.Anthropic()
response = client.messages.count_tokens(
model="claude-opus-5",
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"],
},
}
],
messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
)
print(response.json())
```
```typescript TypeScript
const client = new Anthropic();
const response = await client.messages.countTokens({
model: "claude-opus-5",
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"]
}
}
],
messages: [{ role: "user", content: "What's the weather like in San Francisco?" }]
});
console.log(response);
```
```csharp C#
using System;
using System.Collections.Generic;
using System.Text.Json;
Cut at 300 lines.