Formato Anthropic
POST /v1/messages recibe una solicitud en el formato Anthropic Messages y responde en el mismo formato, con streaming o sin él. Úsalo con el SDK de Anthropic y con herramientas basadas en él, como Claude Code: configura la URL base, usa tu clave API de Shannon e indica un id de modelo de Shannon.
POST https://api.shannon-ai.com/v1/messages
Apunta el SDK de Anthropic a la URL base de Shannon. El SDK añade /v1/messages y envía tu clave en el header x-api-key.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Say hello in one sentence."}],
)
for block in message.content:
if block.type == "text":
print(block.text) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Say hello in one sentence." }],
});
for (const block of message.content) {
if (block.type === "text") console.log(block.text);
} curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Say hello in one sentence."}]
}' La respuesta es un mensaje cuyo content es una lista de bloques. Encuentra los bloques por su type: cuando el modelo razonó, el primer bloque es thinking y el texto viene después.
{
"id": "msg_5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"type": "message",
"role": "assistant",
"model": "shannon-3",
"content": [
{
"type": "thinking",
"thinking": "The user wants a greeting in one sentence. Keep it short and friendly."
},
{
"type": "text",
"text": "Hello, it is good to meet you."
}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 1184,
"output_tokens": 46
}
} Headers
| Header | Valor | Descripción |
|---|---|---|
x-api-key | YOUR_API_KEY | Tu clave API. En su lugar se acepta Authorization: Bearer YOUR_API_KEY. |
content-type | application/json | Obligatorio. |
anthropic-version | 2023-06-01 | Se acepta, no es obligatorio. El SDK de Anthropic envía 2023-06-01; la respuesta tiene el mismo formato sea cual sea el valor. |
anthropic-beta | Se acepta, no es obligatorio. | |
x-request-id | Opcional. Tu propio id para la solicitud. Vuelve sin cambios en la respuesta; sin él, la respuesta lleva un id de 12 caracteres hexadecimales. |
Campos de solicitud
Solo messages es obligatorio. La columna Aplicado por indica los modelos en los que un campo cambia la respuesta. Los modelos de pesos abiertos alojados son los doce ids de la lista de modelos; la familia Shannon 3 es shannon-3, shannon-3-pro, shannon-3.1 y shannon-3.1-pro. Modelos y precios
| Campo | Tipo | Predeterminado | Descripción | Aplicado por |
|---|---|---|---|---|
model | string | shannon-1.6-lite | Un id de modelo de Shannon de la lista de modelos. Envíalo en cada solicitud. La comparación no distingue mayúsculas de minúsculas. Cualquier otro nombre devuelve 400 unknown model, así que una herramienta que envía sus propios nombres de modelo debe configurarse con un id de Shannon. | Todos los modelos |
messages | array | Obligatorio. La conversación, del mensaje más antiguo al más reciente, con los roles user y assistant. Consulta Mensajes y bloques de contenido más abajo. | Todos los modelos | |
system | string | array | Instrucciones para el modelo: una cadena o un array de bloques de texto. Consulta System prompt más abajo. | Modelos de pesos abiertos alojados, shannon-1.6-*, shannon-2-*, shannon-coder-1 | |
max_tokens | integer | 4096 | Límite superior de la respuesta, en tokens. Opcional en este endpoint; el SDK de Anthropic siempre lo envía. Un valor fuera del rango de 1 a 65,536 se ajusta a ese rango. Es también la cantidad que se reserva de tu saldo mientras se ejecuta la solicitud. | Modelos de pesos abiertos alojados, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
stream | boolean | false | true envía la respuesta como server-sent events. Consulta Streaming más abajo. | Todos los modelos |
temperature | number | Temperatura de muestreo. En los modelos de pesos abiertos alojados los valores se mantienen entre 0 y 2. | Modelos de pesos abiertos alojados, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | |
top_p | number | Muestreo por núcleo (nucleus sampling). | Modelos de pesos abiertos alojados | |
stop_sequences | array | Hasta 4 cadenas. La respuesta termina antes de la primera que aparezca. stop_reason sigue siendo end_turn. | Modelos de pesos abiertos alojados | |
tools | array | Las herramientas que el modelo puede llamar, cada una como {"name", "description", "input_schema"}. Consulta Herramientas más abajo. | Todos los modelos | |
tool_choice | object | {"type": "auto"} deja que el modelo decida, {"type": "any"} lo obliga a llamar a una herramienta, {"type": "tool", "name": "…"} lo obliga a llamar a esa herramienta. | Modelos de pesos abiertos alojados | |
thinking | object | Cuánto razona el modelo antes de responder. Consulta Thinking más abajo. | Modelos de pesos abiertos alojados | |
web_search | boolean | false | Una adición de Shannon al formato: true permite que el modelo busque en la web antes de responder. | shannon-1.6-*, shannon-2-*, familia Shannon 3 |
Sin max_tokens el valor es 4,096, y 65,536 en shannon-coder-1.
Se aceptan metadata, top_k, service_tier y los marcadores cache_control en los bloques para que el código de cliente existente funcione sin cambios. No modifican la respuesta; el prompt caching en los modelos de pesos abiertos alojados es automático.
Una respuesta JSON según un esquema se pide con response_format en Chat Completions y con text.format en Responses. Salidas estructuradas
Una solicitud con system prompt y thinking
Esta solicitud envía un system prompt, un presupuesto de thinking, una temperatura y una secuencia de parada. Usa un modelo de pesos abiertos alojado, que aplica todos ellos.
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
message = client.messages.create(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens=4096,
system="You are a physics teacher. Answer in two sentences.",
thinking={"type": "enabled", "budget_tokens": 2048},
temperature=0.3,
stop_sequences=["\n\n"],
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
for block in message.content:
if block.type == "thinking":
print("reasoning:", block.thinking)
elif block.type == "text":
print("answer:", block.text)
print(message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const message = await client.messages.create({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
max_tokens: 4096,
system: "You are a physics teacher. Answer in two sentences.",
thinking: { type: "enabled", budget_tokens: 2048 },
temperature: 0.3,
stop_sequences: ["\n\n"],
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
for (const block of message.content) {
if (block.type === "thinking") console.log("reasoning:", block.thinking);
if (block.type === "text") console.log("answer:", block.text);
}
console.log(message.usage); curl https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"max_tokens": 4096,
"system": "You are a physics teacher. Answer in two sentences.",
"thinking": {"type": "enabled", "budget_tokens": 2048},
"temperature": 0.3,
"stop_sequences": ["\n\n"],
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}' En los modelos de pesos abiertos alojados, usage informa de los tokens leídos de la caché de prompts por separado de los demás tokens de entrada.
{
"usage": {
"input_tokens": 31,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"output_tokens": 62
}
} System prompt
system es una cadena o un array de bloques de texto con la forma [{"type": "text", "text": "…"}]. Los textos de los bloques se unen con un salto de línea.
Lo aplican los modelos de pesos abiertos alojados, shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro y shannon-coder-1. Con un id de la familia Shannon 3, pon las instrucciones que deben cumplirse en el mensaje del usuario.
Mensajes y bloques de contenido
Un mensaje tiene un role, user o assistant, y un content. content es una cadena o un array de bloques.
| Bloque | Descripción | Disponible en |
|---|---|---|
{"type": "text", "text": "…"} | Texto. | Todos los modelos |
{"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "…"}}{"type": "image", "source": {"type": "url", "url": "…"}} | Una imagen en un mensaje user, en base64 o por URL. | Familia Shannon 3, shannon-1.6-lite, shannon-1.6-pro y los modelos de pesos abiertos alojados que indican entrada de imágenes |
{"type": "document", "source": {"type": "base64", "media_type": "application/pdf", "data": "…"}} | Un documento (PDF, Word, PowerPoint o Excel) en un mensaje user, en base64 o por URL. | Familia Shannon 3 |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | En un mensaje assistant: una llamada a herramienta que el modelo hizo en una respuesta anterior. | Todos los modelos |
{"type": "tool_result", "tool_use_id": "toolu_…", "content": "…"} | En un mensaje user: el resultado de esa llamada. content es una cadena o una lista de bloques de texto. | Todos los modelos |
Puedes reenviar tal cual el content de una respuesta anterior: los bloques text y tool_use se leen, los bloques thinking se omiten.
En los niveles de Shannon, las imágenes y los documentos se leen del último mensaje user. Los tamaños y límites tienen su propia página. Imágenes y archivos
Thinking
Los modelos de pesos abiertos alojados asignan thinking a un esfuerzo de razonamiento. Sin el campo, el esfuerzo es alto.
| Forma | budget_tokens | Efecto |
|---|---|---|
{"type": "disabled"} | Sin razonamiento. La respuesta no tiene bloque thinking. | |
{"type": "enabled", "budget_tokens": 2048} | ≤ 2,048 | Esfuerzo bajo. |
{"type": "enabled", "budget_tokens": 8192} | ≤ 8,192 | Esfuerzo medio. |
{"type": "enabled", "budget_tokens": 16000} | > 8,192 | Esfuerzo alto. |
Un modelo que razona devuelve su razonamiento como un bloque {"type": "thinking", "thinking": "…"} antes del texto. Los niveles de Shannon que razonan también lo envían.
Los esfuerzos se describen en su propia página. Esfuerzo de razonamiento
Herramientas
Una herramienta es una función que ejecuta tu código. Describe cada una con un name, una description y un input_schema. Cuando el modelo quiere una herramienta, la respuesta contiene un bloque tool_use y stop_reason es tool_use.
Una definición de herramienta en tools:
[
{
"name": "get_weather",
"description": "Current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
] El content de una respuesta que la llama:
[
{
"type": "text",
"text": ""
},
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
] Ejecuta la herramienta y luego envía la solicitud de nuevo con la llamada y un bloque tool_result añadidos a messages:
[
{
"role": "user",
"content": "What is the weather in Paris?"
},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"input": {
"city": "Paris"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"content": "{\"temperature_c\": 18, \"sky\": \"cloudy\"}"
}
]
}
] tool_choice
| Forma | Efecto | Aplicado por |
|---|---|---|
{"type": "auto"} | El modelo decide si llama a una herramienta. Es el valor predeterminado. | Todos los modelos |
{"type": "any"} | El modelo debe llamar a una de las herramientas. | Modelos de pesos abiertos alojados |
{"type": "tool", "name": "…"} | El modelo debe llamar a la herramienta indicada. | Modelos de pesos abiertos alojados |
Solo se leen las herramientas con un input_schema. La búsqueda web no es una herramienta en este endpoint: usa el campo web_search.
El bucle de herramientas se describe por completo en su propia página. Llamadas a funciones
La respuesta
| Campo | Tipo | Descripción | Enviado por |
|---|---|---|---|
id | string | msg_ seguido de 32 caracteres hexadecimales. | Todos los modelos |
type | string | Siempre message. | Todos los modelos |
role | string | Siempre assistant. | Todos los modelos |
model | string | El id canónico del modelo que respondió. | Todos los modelos |
content | array | Los bloques de la respuesta, en este orden: thinking cuando el modelo razonó, text y después un tool_use por cada llamada a herramienta. | Todos los modelos |
stop_reason | string | Por qué terminó la respuesta. Consulta los valores más abajo. | Todos los modelos |
usage | object | input_tokens y output_tokens. | Todos los modelos |
sources | array | Solo en una solicitud con web_search: true cuya búsqueda encontró algo: los resultados que recibió el modelo, cada uno con index, title y url. [1] en la respuesta es la entrada con index 1. En un stream llega con el evento message_delta. | shannon-1.6-*, shannon-2-*, familia Shannon 3 |
usage.cache_read_input_tokens | integer | cache_read_input_tokens es la parte del prompt leída de la caché; input_tokens es el resto. cache_creation_input_tokens es siempre 0. | Modelos de pesos abiertos alojados |
Bloques de la respuesta
| Bloque | Descripción |
|---|---|
{"type": "thinking", "thinking": "…"} | El razonamiento del modelo. No hay miembro signature. |
{"type": "text", "text": "…"} | El texto de la respuesta. Puede estar vacío cuando la respuesta es una llamada a herramienta. |
{"type": "tool_use", "id": "toolu_…", "name": "…", "input": {…}} | Una llamada a herramienta. input es un objeto JSON. Envía el resultado de vuelta con el mismo id. |
stop_reason
| stop_reason | Descripción | Enviado por |
|---|---|---|
end_turn | El modelo terminó su respuesta, o apareció una de tus stop_sequences. | Todos los modelos |
tool_use | La respuesta contiene una o más llamadas a herramientas. | Todos los modelos |
max_tokens | La respuesta se cortó en el límite de salida. | Familia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1, en streams |
Streaming
Establece stream en true para recibir server-sent events. Cada trama tiene una línea event: con el nombre del evento y una línea data: con un objeto JSON que repite el nombre en type. Los ayudantes de stream del SDK de Anthropic leen estos eventos por ti:
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com",
)
with client.messages.stream(
model="shannon-3",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain server-sent events in three sentences."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
message = stream.get_final_message()
print()
print(message.stop_reason, message.usage) import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com",
});
const stream = client.messages.stream({
model: "shannon-3",
max_tokens: 1024,
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
});
stream.on("text", (text) => process.stdout.write(text));
const message = await stream.finalMessage();
console.log("\n", message.stop_reason, message.usage); curl -N https://api.shannon-ai.com/v1/messages \
-H "x-api-key: YOUR_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "shannon-3",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}]
}' Los eventos, en el orden en que llegan:
| Evento | Datos | Cuándo |
|---|---|---|
message_start | message | Siempre el primero. message contiene el id, el rol, el modelo, un content vacío y un usage que empieza en cero. |
content_block_start | index, content_block | Se abre un bloque. content_block es un bloque text o thinking vacío, o un bloque tool_use con su id y name. |
content_block_delta | index, delta {"type": "thinking_delta", "thinking"} | Un fragmento del razonamiento, para un bloque thinking. |
content_block_delta | index, delta {"type": "text_delta", "text"} | Un fragmento de la respuesta, para un bloque text. |
content_block_delta | index, delta {"type": "input_json_delta", "partial_json"} | Los argumentos de una llamada a herramienta, completos en un solo delta, para un bloque tool_use. |
content_block_stop | index | El bloque con este index está completo. |
message_delta | delta {stop_reason, stop_sequence}, usage | El final de la respuesta: delta.stop_reason y el usage de la solicitud. |
message_stop | Siempre el último. |
Los bloques se numeran con index en el orden en que se abren, y un bloque se completa antes de que se abra el siguiente. Lee cada bloque por su tipo, no por su número: un stream puede abrir primero un bloque text vacío, luego el bloque thinking, y entregar la respuesta en un bloque text posterior.
event: message_start
data: {"type":"message_start","message":{"id":"msg_5f0c…","type":"message","role":"assistant","model":"shannon-3","content":[],"usage":{"input_tokens":0,"output_tokens":0}}}
event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: content_block_start
data: {"type":"content_block_start","index":1,"content_block":{"type":"thinking","thinking":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"thinking_delta","thinking":"Three sentences: what it is, how it is framed, why it is used."}}
event: ping
data: {"type": "ping"}
event: content_block_stop
data: {"type":"content_block_stop","index":1}
event: content_block_start
data: {"type":"content_block_start","index":2,"content_block":{"type":"text","text":""}}
event: content_block_delta
data: {"type":"content_block_delta","index":2,"delta":{"type":"text_delta","text":"Server-sent events let a server push text over one HTTP reply."}}
event: content_block_stop
data: {"type":"content_block_stop","index":2}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":1190,"output_tokens":84}}
event: message_stop
data: {"type":"message_stop"} Keep-alive
| Enviado por | Descripción |
|---|---|
Familia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | Un evento ping con los datos {"type": "ping"}, cada 15 segundos. |
| Modelos de pesos abiertos alojados | Una línea de comentario : keepalive, cada 15 segundos mientras el modelo trabaja. |
Un stream que falla
Un fallo después de que el stream haya empezado es un evento error con el mismo cuerpo que una respuesta de error: {"type": "error", "error": {"type", "message"}}. Los eventos de cierre, message_delta y message_stop, siguen llegando. Considera la respuesta como fallida y envía la solicitud de nuevo.
Errores
Los errores usan el cuerpo de error de Anthropic: type es error y el objeto error contiene un type y un message. La tabla muestra lo que este endpoint devuelve con más frecuencia. La lista completa, con qué reintentar, tiene su propia página. Manejo de errores
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} | Estado | Tipo | Mensaje | Cuándo |
|---|---|---|---|
401 | authentication_error | Missing authenticationInvalid API key | No se envió ninguna clave API, o la clave es desconocida o está revocada. |
400 | invalid_request_error | unknown model: <id> | model no es un id de modelo de Shannon. |
400 | invalid_request_error | No user message provided | Niveles de Shannon: la solicitud no tiene texto de usuario ni tools. |
400 | invalid_request_error | <id> does not accept image input | Se envió una imagen a un modelo de pesos abiertos alojado sin entrada de imágenes. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Falta messages, o un campo tiene un tipo JSON incorrecto. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | max_tokens es mayor que lo que queda de tu saldo. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Protección contra flood: más de 120 solicitudes en un minuto en tu cuenta. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1: se agotaron las llamadas de Shannon Coder de tu plan para la ventana actual de 4 horas. |
500 | server_error | The model backend failed to answer. Please retry. | El modelo no produjo una respuesta. Envía la solicitud de nuevo. |
502 | api_error | The model backend failed to answer. Please retry. | El modelo no produjo una respuesta. Envía la solicitud de nuevo. |
Contar tokens
POST /v1/messages/count_tokens recibe el mismo cuerpo que una solicitud de mensaje (model, system, messages, tools) y devuelve {"input_tokens": n}: el número de tokens de entrada que se cobrarían por la solicitud. Cuenta para los modelos de pesos abiertos alojados, es gratis y la protección contra flood no lo cuenta.
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 physics teacher. Answer in two sentences.",
messages=[{"role": "user", "content": "Why is the sky blue?"}],
)
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 physics teacher. Answer in two sentences.",
messages: [{ role: "user", content: "Why is the sky blue?" }],
});
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 physics teacher. Answer in two sentences.",
"messages": [{"role": "user", "content": "Why is the sky blue?"}]
}'
# {"input_tokens": 31} El conteo tiene su propia página, con el endpoint de texto plano y los límites. Conteo de tokens