Conteo de tokens
Cuenta los tokens de un texto o de una solicitud completa antes de enviarla.
POST https://api.shannon-ai.com/v1/tokenize
POST https://api.shannon-ai.com/v1/messages/count_tokens
Ambos endpoints cuentan con el tokenizador del modelo que nombras, y no se ejecuta ningún modelo. Cubren los modelos de pesos abiertos alojados. /v1/tokenize recibe un texto simple o una conversación de Chat Completions. /v1/messages/count_tokens recibe una solicitud en el formato Anthropic Messages, que es la llamada que hacen el SDK de Anthropic y Claude Code.
Contar es gratis. Una llamada necesita tu clave API, no descuenta nada de tu saldo y no aparece en tu registro de uso.
Contar un texto
Envía model y text. El texto se cuenta tal cual, sin formato de chat a su alrededor.
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
} Los números en las respuestas de esta página son ejemplos. El mismo texto da un conteo distinto en un modelo distinto.
Contar una solicitud de chat
Envía model y messages, con tools cuando la solicitud los tenga, exactamente como los enviarías a /v1/chat/completions. La respuesta es el tamaño de toda la entrada.
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
} Campos de /v1/tokenize
| Campo | Tipo | Descripción |
|---|---|---|
model | string | Obligatorio. Un id de modelo de pesos abiertos alojado. Las mayúsculas y minúsculas se tratan igual. |
text | string | Un texto para contar tal cual, sin formato de chat. Hasta 4,000,000 bytes. Envía text o messages; cuando están ambos, se cuenta text. |
messages | array | Mensajes de chat en el formato de Chat Completions. Se cuentan como la entrada completa de una solicitud: cada mensaje con el formato que la plantilla de chat del modelo pone a su alrededor. |
tools | array | Definiciones de herramientas que se incluyen en el conteo. Se usan junto con messages. |
La respuesta es un objeto JSON con estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
model | string | El id del modelo para el que se hizo el conteo, con su escritura publicada. |
tokens | integer | Con text: los tokens del texto. Con messages: los tokens de toda la entrada, imágenes incluidas. |
Contar una solicitud de Messages
Envía el cuerpo que enviarías a /v1/messages: model, messages, y system y tools cuando los uses. Los SDK oficiales de Anthropic llaman a este endpoint mediante 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
} Campos de /v1/messages/count_tokens
| Campo | Tipo | Descripción |
|---|---|---|
model | string | Obligatorio. Un id de modelo de pesos abiertos alojado. |
messages | array | Obligatorio. Mensajes en el formato Anthropic Messages. Se cuentan los bloques text, image, tool_use y tool_result. |
system | string | array | El system prompt: una cadena o un array de bloques de texto. |
tools | array | Definiciones de herramientas con name, description e input_schema. |
Se aceptan por compatibilidad, sin efecto en el conteo: tool_choice, max_tokens, temperature, top_p, stop_sequences, stream, thinking. Puedes pasar el cuerpo de una solicitud real sin cambios.
La respuesta es un objeto JSON con estos campos:
| Campo | Tipo | Descripción |
|---|---|---|
input_tokens | integer | Los tokens de toda la entrada: system prompt, mensajes, herramientas e imágenes. |
Modelos compatibles
Ambos endpoints cuentan para los modelos de pesos abiertos alojados. GET /v1/models enumera /v1/tokenize y /v1/messages/count_tokens en los endpoints de cada modelo que los admite. Cualquier otro valor de model, incluidos los ids de Shannon, se responde con 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
Para un modelo Shannon, lee el conteo de tokens del objeto usage de una respuesta.
Cómo se hace el conteo
Cada modelo se cuenta con su propio tokenizador y su propia plantilla de chat. No se usa ninguna estimación a partir de caracteres o palabras.
| Qué se cuenta | Regla |
|---|---|
| Un texto | Los tokens de la cadena tal como se envía. Una cadena vacía cuenta 0. |
| Mensajes | Los mensajes y las herramientas se disponen con la plantilla de chat propia del modelo, hasta el punto donde empieza la respuesta, y se cuenta todo ese prompt. |
| Roles | Se cuentan los mensajes system, user, assistant y tool. developer se cuenta como system. Un mensaje sin contenido y sin llamada a herramienta no suma nada. |
| Llamadas a herramientas y resultados | Las llamadas a herramientas de turnos anteriores del asistente y sus resultados forman parte del conteo, en ambos endpoints. |
| Imágenes | Una imagen enviada dentro del cuerpo (base64 o una URL data:) suma un token por cada parche de 28 × 28 píxeles: ceil(width / 28) × ceil(height / 28). Una imagen dada como URL http(s) no la descargan estos endpoints y cuenta 1,024. |
Ejemplo: una imagen de 1,024 × 768 píxeles cuenta ceil(1024 / 28) × ceil(768 / 28) = 37 × 28 = 1,036 tokens.
El conteo y lo que se cobra por una solicitud
El conteo de una solicitud completa se hace igual que el conteo de entrada de una solicitud real con el mismo modelo, mensajes y herramientas. Una respuesta informa ese número como usage.prompt_tokens en Chat Completions, como usage.input_tokens en Responses, y como usage.input_tokens más usage.cache_read_input_tokens en Messages.
- El conteo es la entrada antes del descuento por entrada en caché. Una solicitud real puede leer parte de esa entrada de la caché y facturar esa parte a la tarifa de caché. Caché de prompts
- Una imagen dada como URL
http(s)cuenta 1,024 aquí. Una solicitud real descarga la imagen y la cuenta según su tamaño en píxeles, así que los dos números pueden diferir. Envía la imagen en base64 para obtener el mismo número. - La salida no forma parte del conteo. La respuesta de una solicitud real se factura además como tokens de salida, razonamiento incluido.
- Un conteo de
textno tiene formato de chat. Úsalo para medir un documento o una parte de un prompt, y la formamessagespara medir una solicitud.
Para convertir un conteo en un costo, multiplícalo por el precio de entrada del modelo por 1M de tokens. Modelos y precios
Límites
| Límite | Valor | Por encima |
|---|---|---|
Longitud de text | 4,000,000 bytes (UTF-8) | 413 con el mensaje text too long |
| Cuerpo de la solicitud | 32 MiB | 413 |
| Por solicitud | Un texto o una conversación | Envía una solicitud por texto para contar varios textos. |
Las llamadas de conteo no cuentan para el límite de 120 solicitudes por minuto. Límites y saldo
Errores
| Estado | Tipo | Mensaje | Cuándo |
|---|---|---|---|
400 | invalid_request_error | tokenize is available for the hosted open models; unknown model: <model> | /v1/tokenize con un model que no es un id de modelo de pesos abiertos alojado. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <model> | /v1/messages/count_tokens con un model que no es un id de modelo de pesos abiertos alojado, o sin model. |
400 | invalid_request_error | send `text` or `messages` | /v1/tokenize sin text ni messages. |
401 | authentication_error | Missing authentication / Invalid API key | No se envió ninguna clave, o la clave no es válida. |
413 | invalid_request_error | text too long | text es más largo que 4,000,000 bytes. Un cuerpo de más de 32 MiB también se responde con 413. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | La solicitud no tiene un content type JSON. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Falta un campo obligatorio (model en /v1/tokenize, messages en /v1/messages/count_tokens) o un campo tiene el tipo incorrecto. |
503 | api_error | token counting is temporarily unavailable for this model | El conteo no se puede hacer para este modelo en este momento. Inténtalo de nuevo más tarde. |
/v1/tokenize devuelve los errores con la forma de OpenAI. En /v1/messages/count_tokens los errores del propio endpoint (400 por el modelo, 503) vienen con la forma de Anthropic, y 401, 413, 415 y 422 vienen con la forma de OpenAI. Lee primero el código de estado, luego error.type y error.message, que están presentes en ambas formas.
{
"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"
}
}