Décompte de tokens
Comptez les tokens d'un texte ou d'une requête entière avant de l'envoyer.
POST https://api.shannon-ai.com/v1/tokenize
POST https://api.shannon-ai.com/v1/messages/count_tokens
Les deux points de terminaison comptent avec le tokenizer du modèle que vous nommez, et aucun modèle ne s'exécute. Ils couvrent les modèles open-weight hébergés. /v1/tokenize prend un texte simple ou une conversation Chat Completions. /v1/messages/count_tokens prend une requête au format Anthropic Messages, qui est l'appel que font le SDK Anthropic et Claude Code.
Le décompte est gratuit. Un appel demande votre clé API, ne prélève rien sur votre solde et n'apparaît pas dans votre journal d'utilisation.
Compter un texte
Envoyez model et text. Le texte est compté tel quel, sans formatage de chat autour.
import requests
response = requests.post(
"https://api.shannon-ai.com/v1/tokenize",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"text": "Hello, world",
},
)
print(response.json()["tokens"]) const response = await fetch("https://api.shannon-ai.com/v1/tokenize", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
text: "Hello, world",
}),
});
const { tokens } = await response.json();
console.log(tokens); curl https://api.shannon-ai.com/v1/tokenize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"text": "Hello, world"
}' {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"tokens": 3
} Les nombres dans les réponses de cette page sont des exemples. Le même texte donne un décompte différent sur un autre modèle.
Compter une requête de chat
Envoyez model et messages, avec tools quand la requête en a, exactement comme vous les enverriez à /v1/chat/completions. La réponse est la taille de toute l'entrée.
import requests
request = {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the weather in Paris?"},
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
],
}
response = requests.post(
"https://api.shannon-ai.com/v1/tokenize",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=request,
)
print(response.json()["tokens"]) const request = {
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
messages: [
{ role: "system", content: "You are a concise assistant." },
{ role: "user", content: "What is the weather in Paris?" },
],
tools: [
{
type: "function",
function: {
name: "get_weather",
description: "Current weather for a city",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
},
],
};
const response = await fetch("https://api.shannon-ai.com/v1/tokenize", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify(request),
});
const { tokens } = await response.json();
console.log(tokens); curl https://api.shannon-ai.com/v1/tokenize \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is the weather in Paris?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}
]
}' {
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"tokens": 164
} Champs de /v1/tokenize
| Champ | Type | Description |
|---|---|---|
model | string | Obligatoire. Un id de modèle open-weight hébergé. Les majuscules et les minuscules sont traitées de la même façon. |
text | string | Un texte à compter tel quel, sans formatage de chat. Jusqu'à 4,000,000 octets. Envoyez text ou messages ; quand les deux sont présents, text est compté. |
messages | array | Messages de chat au format Chat Completions. Ils sont comptés comme l'entrée complète d'une requête : chaque message avec le formatage que le modèle de chat du modèle place autour. |
tools | array | Des définitions d'outils à inclure dans le décompte. Utilisées avec messages. |
La réponse est un objet JSON avec ces champs :
| Champ | Type | Description |
|---|---|---|
model | string | L'id du modèle pour lequel le décompte a été fait, dans son écriture publiée. |
tokens | integer | Avec text : les tokens du texte. Avec messages : les tokens de toute l'entrée, images comprises. |
Compter une requête Messages
Envoyez le corps que vous enverriez à /v1/messages : model, messages, et system et tools si vous les utilisez. Les SDK Anthropic officiels appellent ce point de terminaison via messages.count_tokens.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
count = client.messages.count_tokens(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system="You are a concise assistant.",
messages=[
{"role": "user", "content": "Summarise the attached report."}
],
)
print(count.input_tokens) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const count = await client.messages.countTokens({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
system: "You are a concise assistant.",
messages: [
{ role: "user", content: "Summarise the attached report." },
],
});
console.log(count.input_tokens); curl https://api.shannon-ai.com/v1/messages/count_tokens \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"system": "You are a concise assistant.",
"messages": [
{"role": "user", "content": "Summarise the attached report."}
]
}' {
"input_tokens": 21
} Champs de /v1/messages/count_tokens
| Champ | Type | Description |
|---|---|---|
model | string | Obligatoire. Un id de modèle open-weight hébergé. |
messages | array | Obligatoire. Messages au format Anthropic Messages. Les blocs text, image, tool_use et tool_result sont comptés. |
system | string | array | Le prompt système : une chaîne ou un tableau de blocs de texte. |
tools | array | Les définitions d'outils avec name, description et input_schema. |
Acceptés par compatibilité, sans effet sur le décompte : tool_choice, max_tokens, temperature, top_p, stop_sequences, stream, thinking. Vous pouvez passer tel quel le corps d'une vraie requête.
La réponse est un objet JSON avec ces champs :
| Champ | Type | Description |
|---|---|---|
input_tokens | integer | Les tokens de toute l'entrée : prompt système, messages, outils et images. |
Modèles pris en charge
Les deux points de terminaison comptent pour les modèles open-weight hébergés. GET /v1/models liste /v1/tokenize et /v1/messages/count_tokens dans les endpoints de chaque modèle qui les prend en charge. Toute autre valeur de model, ids Shannon compris, reçoit la réponse 400.
DeepSeek-V4-Pro-0813-3BIT-REAPGLM-5.2-3BIT-REAPKimi-K3-3BIT-REAPNemotron3Ultra-3BIT-REAPMiniMax-M3-3BIT-REAPDeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAPKimi-K2.6-W4A16-AUTOROUND-REAPLaguna-S-2.1-W4A16-AUTOROUND-REAPinkling-W4A16-AUTOROUND-REAPMiMo-V2.5-Pro-W8A16MiMo-V2.5-W8A16Hy3-W8A16
Pour un modèle Shannon, lisez les décomptes de tokens dans l'objet usage d'une réponse.
Comment le décompte est fait
Chaque modèle est compté avec son propre tokenizer et son propre modèle de chat. Aucune estimation à partir des caractères ou des mots n'est utilisée.
| Ce qui est compté | Règle |
|---|---|
| Un texte | Les tokens de la chaîne telle qu'elle est envoyée. Une chaîne vide compte 0. |
| Messages | Les messages et les outils sont disposés avec le modèle de chat propre au modèle, jusqu'au point où la réponse commence, et tout ce prompt est compté. |
| Rôles | Les messages system, user, assistant et tool sont comptés. developer est compté comme system. Un message sans contenu ni appel d'outil n'ajoute rien. |
| Appels d'outil et résultats | Les appels d'outil des tours précédents de l'assistant et leurs résultats font partie du décompte, sur les deux points de terminaison. |
| Images | Une image envoyée dans le corps (base64 ou URL data:) ajoute un token par bloc de 28 × 28 pixels : ceil(width / 28) × ceil(height / 28). Une image donnée sous forme d'URL http(s) n'est pas téléchargée par ces points de terminaison et compte 1,024. |
Exemple : une image de 1,024 × 768 pixels compte ceil(1024 / 28) × ceil(768 / 28) = 37 × 28 = 1,036 tokens.
Le décompte et ce qu'une requête coûte
Le décompte d'une requête entière se fait de la même façon que le décompte d'entrée d'une vraie requête avec le même modèle, les mêmes messages et les mêmes outils. Une réponse indique ce nombre comme usage.prompt_tokens sur Chat Completions, comme usage.input_tokens sur Responses, et comme usage.input_tokens plus usage.cache_read_input_tokens sur Messages.
- Le décompte est l'entrée avant la remise sur l'entrée en cache. Une vraie requête peut lire une partie de cette entrée depuis le cache et facturer cette partie au tarif du cache. Mise en cache du prompt
- Une image donnée sous forme d'URL
http(s)compte 1,024 ici. Une vraie requête télécharge l'image et la compte d'après sa taille en pixels, donc les deux nombres peuvent différer. Envoyez l'image en base64 pour obtenir le même nombre. - La sortie ne fait pas partie du décompte. La réponse d'une vraie requête est facturée en plus comme tokens de sortie, raisonnement compris.
- Un décompte
textn'a aucun formatage de chat. Utilisez-le pour mesurer un document ou une partie de prompt, et la formemessagespour mesurer une requête.
Pour convertir un décompte en coût, multipliez-le par le prix d'entrée du modèle par 1M de tokens. Modèles et tarifs
Limites
| Limite | Valeur | Au-delà |
|---|---|---|
Longueur de text | 4,000,000 octets (UTF-8) | 413 avec le message text too long |
| Corps de la requête | 32 MiB | 413 |
| Par requête | Un texte ou une conversation | Pour compter plusieurs textes, envoyez une requête par texte. |
Les appels de décompte ne comptent pas dans la limite de 120 requêtes par minute. Limites et solde
Erreurs
| Statut | Type | Message | Quand |
|---|---|---|---|
400 | invalid_request_error | tokenize is available for the hosted open models; unknown model: <model> | /v1/tokenize avec un model qui n'est pas un id de modèle open-weight hébergé. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <model> | /v1/messages/count_tokens avec un model qui n'est pas un id de modèle open-weight hébergé, ou sans model. |
400 | invalid_request_error | send `text` or `messages` | /v1/tokenize sans text ni messages. |
401 | authentication_error | Missing authentication / Invalid API key | Aucune clé n'a été envoyée, ou la clé n'est pas valide. |
413 | invalid_request_error | text too long | text dépasse 4,000,000 octets. Un corps de plus de 32 MiB reçoit aussi la réponse 413. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | La requête n'a pas de type de contenu JSON. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Un champ obligatoire est absent (model sur /v1/tokenize, messages sur /v1/messages/count_tokens) ou un champ a un type incorrect. |
503 | api_error | token counting is temporarily unavailable for this model | Le décompte ne peut pas être fait pour ce modèle en ce moment. Réessayez plus tard. |
/v1/tokenize renvoie les erreurs au format OpenAI. Sur /v1/messages/count_tokens, les erreurs propres au point de terminaison (400 pour le modèle, 503) arrivent au format Anthropic, et 401, 413, 415 et 422 arrivent au format OpenAI. Lisez d'abord le code de statut, puis error.type et error.message, qui sont présents dans les deux formats.
{
"error": {
"type": "invalid_request_error",
"message": "tokenize is available for the hosted open models; unknown model: shannon-3"
}
} {
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "count_tokens is available for the hosted open models; unknown model: shannon-3"
}
}