API Responses
NouveauPOST /v1/responses prend des instructions et une liste d'éléments d'entrée et renvoie un objet de réponse composé d'éléments de sortie, au format OpenAI Responses. Utilisez-le avec l'API responses du SDK OpenAI et avec les outils construits dessus, comme Codex CLI. Le point de terminaison ne garde aucun état : envoyez toute la conversation à chaque requête.
POST https://api.shannon-ai.com/v1/responses
La plus petite requête est un id de modèle et un texte. La réponse n'est pas envoyée en streaming sauf si vous le demandez.
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
response = client.responses.create(
model="shannon-3",
input="Say hello in one sentence.",
)
print(response.output_text) import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const response = await client.responses.create({
model: "shannon-3",
input: "Say hello in one sentence.",
});
console.log(response.output_text); curl https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"input": "Say hello in one sentence."
}' La réponse est un objet response. Son output contient le raisonnement, quand le modèle a raisonné, et le message :
{
"id": "resp_5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "response",
"created_at": 1791625200,
"model": "shannon-3",
"status": "completed",
"error": null,
"incomplete_details": null,
"instructions": null,
"metadata": {},
"parallel_tool_calls": true,
"temperature": null,
"tool_choice": "auto",
"tools": [],
"top_p": null,
"output": [
{
"id": "rs_8a2e6c1f4b7d4e03b9c5a1d70f3e2b64",
"type": "reasoning",
"summary": [
{
"type": "summary_text",
"text": "The user wants a greeting in one sentence. Keep it short and friendly."
}
]
},
{
"id": "msg_1c7b9e3a5d2f4a86b0e4c8d19a6f7e25",
"type": "message",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "Hello, it is good to meet you.",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 1184,
"output_tokens": 46,
"total_tokens": 1230
}
} Champs de requête
model et input sont ce dont une requête a besoin. La colonne Appliqué par nomme les modèles sur lesquels un champ change la réponse. Les modèles open-weight hébergés sont les douze ids de la liste des modèles ; la famille Shannon 3 est shannon-3, shannon-3-pro, shannon-3.1 et shannon-3.1-pro. Modèles et tarifs
| Champ | Type | Par défaut | Description | Appliqué par |
|---|---|---|---|---|
model | string | Obligatoire. Un id de la liste des modèles. La casse n'a pas d'importance. Un id absent ou non publié renvoie 400 unknown model. | Tous les modèles | |
input | string | array | Une chaîne, lue comme un seul message d'utilisateur, ou un tableau d'éléments d'entrée. Voir Éléments d'entrée plus bas. | Tous les modèles | |
instructions | string | Instructions pour le modèle, le prompt système de ce format. | Modèles open-weight hébergés, shannon-1.6-*, shannon-2-*, shannon-coder-1 | |
stream | boolean | false | true envoie la réponse sous forme de server-sent events. Voir Streaming plus bas. | Tous les modèles |
max_output_tokens | integer | 4096 | Limite supérieure de la réponse, en tokens. Une valeur hors de 1 à 65,536 est ramenée dans cet intervalle. C'est aussi le montant mis de côté sur votre solde pendant l'exécution de la requête. Voir Limite de sortie plus bas. | Modèles open-weight hébergés, shannon-1.6-*, shannon-2-*, shannon-coder-1 |
temperature | number | Température d'échantillonnage. Sur les modèles open-weight hébergés, les valeurs sont maintenues entre 0 et 2. | Modèles open-weight hébergés ; shannon-1.6-*, shannon-2-* et shannon-coder-1 pour les réponses sans streaming | |
top_p | number | Échantillonnage par noyau. Les valeurs sont maintenues entre 0 et 1. | Modèles open-weight hébergés | |
tools | array | Les fonctions que le modèle peut appeler, sous la forme à plat de ce format : {"type": "function", "name", "description", "parameters"}. Voir Outils plus bas. | Tous les modèles | |
tool_choice | string | object | auto | "auto" laisse le modèle décider. "required" l'oblige à appeler un outil. {"type": "function", "name": "…"} l'oblige à appeler cet outil. | Modèles open-weight hébergés |
reasoning | object | {"effort": "…"} avec off, low, medium ou high. Toute autre valeur renvoie 400. | Modèles open-weight hébergés | |
text | object | {"format": {…}} demande une réponse JSON. Voir Sortie structurée plus bas. | Tous les niveaux Shannon ; modèles open-weight hébergés selon l'indication de chaque id |
previous_response_id, store, metadata, parallel_tool_calls, truncation, include, user et prompt_cache_key sont acceptés pour que le code client existant fonctionne sans changement. Ils ne modifient pas la réponse. Comme aucune conversation n'est stockée, une requête de suite porte les tours précédents dans input.
Éléments d'entrée
Un élément d'entrée est soit un message, avec un role et un content, soit un élément typé qui porte un appel d'outil ou son résultat. content est une chaîne ou un tableau de parties.
| Élément | Description | Appliqué par |
|---|---|---|
{"role": "user", "content": …} | Ce que vous demandez. content est une chaîne, ou des parties input_text et input_image. | Tous les modèles |
{"role": "assistant", "content": …} | Une réponse précédente du modèle. content est une chaîne, ou des parties output_text. | Tous les modèles |
{"role": "system", "content": …}{"role": "developer", "content": …} | Instructions à l'intérieur de la conversation. | Modèles open-weight hébergés |
{"type": "function_call", "call_id": "…", "name": "…", "arguments": "…"} | Un appel d'outil fait par le modèle dans une réponse précédente. arguments est une chaîne JSON. | Tous les modèles |
{"type": "function_call_output", "call_id": "…", "output": "…"} | Le résultat de cet appel. call_id est l'id de l'appel et output le résultat sous forme de chaîne. | Tous les modèles |
Mettez les instructions dans le champ instructions. Avec un id de la famille Shannon 3, mettez les instructions qui doivent être respectées dans le message user.
Les éléments d'output d'une réponse peuvent retourner dans input tels quels : les éléments message et function_call sont lus, les éléments reasoning sont ignorés.
Parties de contenu
| Partie | Description | Disponible sur |
|---|---|---|
{"type": "input_text", "text": "…"} | Texte d'un message d'utilisateur. | Tous les modèles |
{"type": "output_text", "text": "…"} | Texte d'un message de l'assistant. | Tous les modèles |
{"type": "input_image", "image_url": "…"} | Une image, sous forme d'URL data: avec un contenu base64 ou d'URL http(s). | Famille Shannon 3, shannon-1.6-lite, shannon-1.6-pro, et les modèles open-weight hébergés qui indiquent l'entrée d'images |
{"type": "input_file", "file_data": "data:application/pdf;base64,…"} | Un document (PDF, Word, PowerPoint ou Excel) : file_data contient une URL data:, ou file_url une URL http(s). | Famille Shannon 3 |
Sur les niveaux Shannon, les images et les fichiers sont lus dans le dernier élément user de input. Les tailles et les limites ont leur propre page. Images et fichiers
Une requête avec instructions et options
Cette requête envoie des instructions, une conversation sous forme d'éléments d'entrée, une limite de sortie, une température et un effort de raisonnement. Elle utilise un modèle open-weight hébergé, qui les applique tous.
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
response = client.responses.create(
model="DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
instructions="You are a physics teacher. Answer in two sentences.",
input=[
{"role": "user", "content": "Why is the sky blue?"},
{"role": "assistant", "content": "Air scatters blue light more than red light."},
{"role": "user", "content": "And why are sunsets red?"},
],
max_output_tokens=512,
temperature=0.3,
reasoning={"effort": "low"},
)
for item in response.output:
if item.type == "reasoning":
print("reasoning:", item.summary[0].text)
elif item.type == "message":
print("answer:", item.content[0].text)
print(response.usage) import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const response = await client.responses.create({
model: "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
instructions: "You are a physics teacher. Answer in two sentences.",
input: [
{ role: "user", content: "Why is the sky blue?" },
{ role: "assistant", content: "Air scatters blue light more than red light." },
{ role: "user", content: "And why are sunsets red?" },
],
max_output_tokens: 512,
temperature: 0.3,
reasoning: { effort: "low" },
});
for (const item of response.output) {
if (item.type === "reasoning") console.log("reasoning:", item.summary[0].text);
if (item.type === "message") console.log("answer:", item.content[0].text);
}
console.log(response.usage); curl https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "DeepSeek-V4-Flash-0731-W4A16-AUTOROUND-REAP",
"instructions": "You are a physics teacher. Answer in two sentences.",
"input": [
{"role": "user", "content": "Why is the sky blue?"},
{"role": "assistant", "content": "Air scatters blue light more than red light."},
{"role": "user", "content": "And why are sunsets red?"}
],
"max_output_tokens": 512,
"temperature": 0.3,
"reasoning": {"effort": "low"}
}' La réponse d'un modèle open-weight hébergé contient id, object, model, created_at, status, output et usage. Son usage ajoute les tokens lus depuis le cache et les tokens consacrés au raisonnement :
{
"usage": {
"input_tokens": 58,
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens": 67,
"output_tokens_details": {
"reasoning_tokens": 19
},
"total_tokens": 125
}
} L'objet de réponse
id, object, status, output et usage figurent dans chaque réponse. Appuyez votre code sur ces champs.
| Champ | Type | Description | Envoyé par |
|---|---|---|---|
id | string | resp_ suivi de 32 caractères hexadécimaux. | Tous les modèles |
object | string | Toujours response. | Tous les modèles |
status | string | completed. Dans un flux, c'est d'abord in_progress, puis failed dans un événement response.failed. | Tous les modèles |
output | array | Les éléments de sortie dans l'ordre où le modèle les a produits : reasoning, message, function_call. | Tous les modèles |
usage | object | input_tokens, output_tokens et total_tokens. | Tous les modèles |
usage.input_tokens_details | object | cached_tokens : les tokens d'entrée lus depuis le cache du prompt. | Modèles open-weight hébergés |
usage.output_tokens_details | object | reasoning_tokens : les tokens de sortie consacrés au raisonnement. | Modèles open-weight hébergés |
model | string | L'id canonique du modèle qui a répondu. | Famille Shannon 3, modèles open-weight hébergés |
created_at | integer | Heure de la réponse, en secondes Unix. | Famille Shannon 3, modèles open-weight hébergés |
instructions, tools, temperature, … | instructions, tools et temperature reprennent la requête. error et incomplete_details valent null, metadata vaut {}, parallel_tool_calls vaut true, tool_choice vaut auto et top_p vaut null. | Famille Shannon 3 |
Éléments de sortie
| Élément | Description |
|---|---|
{"id": "rs_…", "type": "reasoning", "summary": [{"type": "summary_text", "text": "…"}]} | Le raisonnement du modèle sous forme d'une partie summary_text. Présent seulement quand le modèle a raisonné. |
{"id": "msg_…", "type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "…"}]} | La réponse : une partie output_text avec le texte. |
{"id": "fc_…", "type": "function_call", "call_id": "call_…", "name": "…", "arguments": "…"} | Un appel d'outil. arguments est une chaîne JSON. Renvoyez le résultat avec le même call_id. |
Les SDK OpenAI assemblent pour vous le texte du message dans response.output_text.
Streaming
Mettez stream à true pour recevoir des server-sent events. Chaque trame a une ligne event: avec le nom de l'événement et une ligne data: avec un objet JSON ; l'objet répète le nom dans type. Associez les deltas à leur élément par output_index.
Avec le SDK OpenAI, lisez les événements par leur type :
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
stream = client.responses.create(
model="shannon-3",
input="Explain server-sent events in three sentences.",
stream=True,
)
for event in stream:
kind = getattr(event, "type", "error") # an event without a type is an error event
if kind == "response.reasoning_summary_text.delta":
pass # a piece of reasoning: event.delta
elif kind == "response.output_text.delta":
print(event.delta, end="", flush=True)
elif kind == "response.output_item.done" and event.item.type == "function_call":
print("\ntool call:", event.item.name, event.item.arguments)
elif kind == "response.completed":
print("\n", event.response.usage)
elif kind in ("response.failed", "error"):
raise RuntimeError("the stream failed, send the request again") import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const stream = await client.responses.create({
model: "shannon-3",
input: "Explain server-sent events in three sentences.",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.reasoning_summary_text.delta") {
// a piece of reasoning: event.delta
} else if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
} else if (event.type === "response.output_item.done" && event.item.type === "function_call") {
console.log("\ntool call:", event.item.name, event.item.arguments);
} else if (event.type === "response.completed") {
console.log("\n", event.response.usage);
} else if (event.type === "response.failed" || event.type === "error") {
throw new Error("the stream failed, send the request again");
}
} curl -N https://api.shannon-ai.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"input": "Explain server-sent events in three sentences.",
"stream": true
}' Les événements arrivent dans cet ordre. Les groupes pour le raisonnement, le message et les appels d'outil n'apparaissent que si la réponse en comporte.
| Événement | Contenu | Quand |
|---|---|---|
response.created | response | Toujours en premier. response.status vaut in_progress et response.output est vide. |
response.in_progress | response | Toujours en deuxième, avec le même objet. |
response.output_item.added | output_index, item | Le raisonnement commence : un élément reasoning avec un summary vide. |
response.reasoning_summary_text.delta | output_index, summary_index, delta | Un morceau du raisonnement. |
response.reasoning_summary_text.done | output_index, summary_index, text | Le raisonnement est complet : son text entier. |
response.output_item.done | output_index, item | L'élément reasoning terminé. |
response.output_item.added | output_index, item | La réponse commence : un élément message avec le statut in_progress et sans contenu. |
response.content_part.added | output_index, content_index, part | Une partie output_text vide s'ouvre. |
response.output_text.delta | output_index, content_index, delta | Un morceau de la réponse. |
response.output_text.done | output_index, content_index, text | La réponse est complète : son text entier. |
response.content_part.done | output_index, content_index, part | La partie output_text terminée. |
response.output_item.done | output_index, item | L'élément message terminé, avec le statut completed. |
response.output_item.added | output_index, item | Un appel d'outil commence : un élément function_call avec call_id, name et arguments vides. |
response.function_call_arguments.delta | output_index, delta | Les arguments de l'appel, complets dans un seul delta. |
response.function_call_arguments.done | output_index, arguments | Les mêmes arguments, sous forme de arguments. |
response.output_item.done | output_index, item | L'élément function_call terminé. |
response.completed | response | Toujours en dernier en cas de succès : l'objet response complet avec output et usage. |
event: response.created
data: {"type":"response.created","response":{"id":"resp_5f0c…","object":"response","status":"in_progress","output":[], …}}
event: response.in_progress
data: {"type":"response.in_progress","response":{"id":"resp_5f0c…","object":"response","status":"in_progress","output":[], …}}
event: response.output_item.added
data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_1c7b…","type":"message","role":"assistant","status":"in_progress","content":[]}}
event: response.content_part.added
data: {"type":"response.content_part.added","output_index":0,"content_index":0,"part":{"type":"output_text","text":""}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":"Server-sent"}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":" events let a server push text over one HTTP reply."}
event: response.output_text.done
data: {"type":"response.output_text.done","output_index":0,"content_index":0,"text":"Server-sent events let a server push text over one HTTP reply."}
event: response.content_part.done
data: {"type":"response.content_part.done","output_index":0,"content_index":0,"part":{"type":"output_text","text":"Server-sent events let a server push text over one HTTP reply."}}
event: response.output_item.done
data: {"type":"response.output_item.done","output_index":0,"item":{"id":"msg_1c7b…","type":"message","role":"assistant","status":"completed","content":[{"type":"output_text","text":"Server-sent events let a server push text over one HTTP reply.","annotations":[]}]}}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_5f0c…","object":"response","status":"completed","output":[…],"usage":{"input_tokens":1190,"output_tokens":18,"total_tokens":1208}, …}} Un flux qui échoue
Sur les niveaux Shannon, une réponse échouée se termine par response.failed à la place de response.completed. Son response.status vaut failed et response.error contient un code, rate_limit_exceeded ou server_error, et un message.
Sur les modèles open-weight hébergés, un échec est un événement error avec code valant api_error et un message. response.completed le suit tout de même.
Considérez un flux comme échoué quand il contient un événement response.failed ou error, et renvoyez la requête.
Outils
Un outil est une fonction que votre code exécute. Décrivez-le dans tools ; quand le modèle le veut, la réponse contient un élément function_call à la place du message, ou à côté de lui.
Une définition d'outil dans tools :
[
{
"type": "function",
"name": "get_weather",
"description": "Current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
] L'output d'une réponse qui l'appelle :
[
{
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function_call",
"name": "get_weather",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"arguments": "{\"city\":\"Paris\"}"
}
] Exécutez la fonction, puis renvoyez la requête avec l'appel et son résultat ajoutés à input :
[
{
"role": "user",
"content": "What is the weather in Paris?"
},
{
"type": "function_call",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
},
{
"type": "function_call_output",
"call_id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"output": "{\"temperature_c\": 18, \"sky\": \"cloudy\"}"
}
] Seuls les outils de type function sont lus. Sur shannon-1.6-*, shannon-2-* et shannon-coder-1, le schéma parameters est réduit aux mots-clés JSON Schema courants : oneOf est lu comme anyOf, et des mots-clés comme $ref, additionalProperties, const, default et title ne sont pas transmis au modèle.
Les valeurs required et une fonction nommée de tool_choice sont appliquées par les modèles open-weight hébergés.
La boucle d'outils est décrite en détail sur sa propre page. Appel de fonction
Sortie structurée
Ce format écrit la sortie structurée sous la forme text.format. Le schéma se trouve directement dans format, à côté de name et strict, et non sous un membre json_schema comme sur Chat Completions.
{"type": "json_object"}demande un objet JSON quelconque.{"type": "json_schema", "name", "schema", "strict"}demande du JSON conforme à votre schéma.strictvauttruequand vous l'omettez.
{
"model": "shannon-1.6-lite",
"input": "Extract the city and the date: 'The conference opens in Lisbon on 12 May 2027.'",
"text": {
"format": {
"type": "json_schema",
"name": "event",
"strict": true,
"schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"date": {
"type": "string",
"description": "ISO 8601 date"
}
},
"required": [
"city",
"date"
]
}
}
}
} Le JSON arrive sous forme de texte dans la partie output_text du message ; analysez-le vous-même. Un modèle open-weight hébergé sans sortie structurée renvoie 400.
{"city": "Lisbon", "date": "2027-05-12"} Quel modèle accepte quelle forme est indiqué sur sa propre page. Résultats structurés
Raisonnement
Un modèle qui raisonne renvoie son raisonnement comme un élément de sortie de type reasoning, avant le message. Dans un flux, il arrive sous forme d'événements response.reasoning_summary_text.delta.
Les modèles open-weight hébergés appliquent reasoning.effort : off, low, medium ou high, avec high quand vous n'envoyez rien. off ne renvoie aucun élément de raisonnement. Envoyez-le comme un objet ; une simple chaîne n'est pas lue sur ce point de terminaison.
Les niveaux d'effort sont décrits sur leur propre page. Effort de raisonnement
Limite de sortie
max_output_tokens vaut 4,096 quand vous ne l'envoyez pas. C'est le nombre de tokens mis de côté sur votre solde au début de la requête ; quand la réponse est complète, ce montant est remplacé par ce que la requête a utilisé. Une valeur qui ne tient pas dans votre solde restant renvoie 429 Quota exceeded.
Il limite la longueur de la réponse sur shannon-1.6-*, shannon-2-* et shannon-coder-1, et la longueur du texte de la réponse sur les modèles open-weight hébergés.
Sur ce point de terminaison, shannon-coder-1 est facturé en tokens sur votre solde, comme tout autre modèle.
Le corps d'une requête peut atteindre 32 MiB. Limites et solde
Erreurs
Les erreurs utilisent le corps d'erreur d'OpenAI : un objet error avec type et message ; certaines portent aussi code et param avec la valeur null. Le tableau liste ce que ce point de terminaison renvoie le plus souvent. La liste complète, avec ce qu'il faut réessayer, a sa propre page. Gestion des erreurs
| Statut | Type | Message | Quand |
|---|---|---|---|
401 | authentication_error | Missing authenticationInvalid API key | Aucune clé API n'a été envoyée, ou la clé est inconnue ou révoquée. |
400 | invalid_request_error | unknown model: <id> | model est absent ou n'est pas un id publié. |
400 | invalid_request_error | No user message provided. | Niveaux Shannon : input ne contient aucun texte d'utilisateur. |
400 | invalid_request_error | <id> does not accept image input | Une image a été envoyée à un modèle open-weight hébergé sans entrée d'images. |
400 | invalid_request_error | <id> does not accept response_format | text.format a été envoyé à un modèle open-weight hébergé sans sortie structurée. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | reasoning.effort contient une valeur hors de la liste. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Le corps est du JSON valide, mais un champ a un type incorrect. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | max_output_tokens est supérieur à ce qui reste de votre solde. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Protection anti-flood : plus de 120 requêtes en une minute sur votre compte. |
500 | api_error | The model backend failed to answer. Please retry. | Le modèle n'a pas produit de réponse. Renvoyez la requête. |
502 | api_error | The model backend failed to answer. Please retry. | Idem, sur les modèles open-weight hébergés. |
504 | api_error | upstream timed out | Un modèle open-weight hébergé a dépassé le délai d'une réponse sans streaming. Envoyez la requête avec stream à true. |