Référence de l'API d'IA
Tous les endpoints d'api.nodion.ai/v1, avec leurs limites et leurs erreurs.
URL de base : https://api.nodion.ai/v1. L'API suit le format d'OpenAI : les SDK OpenAI fonctionnent
si vous les configurez avec cette URL de base. Pour les clés, le solde et les onglets du dashboard, consultez
AI Inference. Les modèles, fournisseurs et prix figurent dans le catalogue des modèles.
pythonimport os
from openai import OpenAI
client = OpenAI(
base_url="https://api.nodion.ai/v1",
api_key=os.environ["NODION_AI_KEY"],
)
reply = client.chat.completions.create(
model="<model>",
messages=[{"role": "user", "content": "Hello"}],
)
print(reply.choices[0].message.content) Authentification
Envoyez une clé d'inférence (nodion_ai_…) comme bearer token dans chaque requête. Les clés de plateforme
(nodion_…) ne fonctionnent pas ici. GET /v1/models est le seul appel qui ne nécessite pas de clé.
httpAuthorization: Bearer nodion_ai_… Une clé refusée entraîne une réponse 401 avec l'un de ces messages :
missing bearer tokeninvalid api keyapi key expiredaccount disabledaccount under review
Chaque réponse comporte un en-tête X-Request-ID. Indiquez-le lorsque vous contactez le support.
Les corps de requête JSON peuvent atteindre 25 MiB (outils 1 MiB, System One 512 KiB). L'encodage base64 augmente la taille des fichiers d'un tiers : un fichier intégré
directement dans le JSON, comme une image, un PDF ou un document OCR, peut donc faire environ 18 MiB. Les envois multipart vers
/v1/audio/transcriptions et /v1/audio/voices peuvent atteindre 25 MiB, avec
des fichiers de transcription jusqu'à 20 MiB et des fichiers d'échantillon de voix jusqu'à 10 MiB (11 MiB pour l'ensemble du
formulaire).
Endpoints
| Endpoint | Rôle | Facturé selon |
|---|---|---|
GET /v1/models | Liste les modèles facturés au token | Gratuit |
POST /v1/chat/completions | Chat, outils, sortie structurée | Tokens d'entrée et de sortie |
POST /v1/responses | OpenAI Responses API, par exemple pour Codex | Tokens d'entrée et de sortie |
POST /v1/embeddings | Embeddings vectoriels | Tokens d'entrée |
POST /v1/rerank | Classe des documents selon une requête de recherche | Tokens d'entrée |
POST /v1/systemone | System One : décisions typées avec probabilités | Tokens d'entrée |
POST /v1/ocr | OCR de documents et d'images | Pages |
POST /v1/audio/transcriptions | Transcription audio (speech-to-text) | Secondes d'audio |
GET /v1/audio/transcriptions/realtime (WebSocket) | Transcription audio en temps réel | Secondes d'audio |
POST /v1/audio/speech | Synthèse vocale (text-to-speech) | Caractères |
GET, POST /v1/audio/voices | Liste et crée des voix clonées | Gratuit |
GET, DELETE /v1/audio/voices/{id} | Lit ou supprime une voix clonée | Gratuit |
POST /v1/images/generations | Génération d'images | Images |
POST /v1/tools/web_search, web_news, web_fetch, web_images, web_videos, web_places, web_maps, web_shopping, web_lens | Outils web | Appels, plus chaque page chargée par un web_search |
L'audio, les images et les outils sont décrits avec des exemples dans AI Inference. Les autres endpoints sont présentés ci-dessous.
Avant chaque appel, un montant correspondant au coût maximal estimé est réservé sur le solde. La requête est ensuite facturée selon l'usage déclaré,
sans dépasser le montant réservé, et le reste est libéré. Si une réponse réussie ne déclare aucun usage, la totalité de la réservation
est facturée. Une session de transcription en temps réel réserve le max_audio_seconds du modèle (1 800 secondes
si le modèle n'en définit pas), donc le solde doit couvrir une session complète à l'avance.
Modèles
GET /v1/models renvoie {"object": "list", "data": [...]} et liste les modèles de chat,
d'embeddings et de rerank. Les modèles OCR, vocaux, d'image et d'outils n'y figurent pas ; le catalogue
public sur https://api.nodion.com/v2/public/ai/models liste tous les types. Champs utiles pour chaque modèle :
id: la valeur demodeldans les requêtes.kind:chat,embeddingsourerank.context_lengthetmax_output_lengthen tokens.pricing: prix en USD par token, sous forme de chaînes décimales.pricing_eurcontient les prix en EUR.supported_sampling_parametersetsupported_features(par exempletools,json_mode,structured_outputs,reasoning).reasoning_efforts: les valeurs dereasoning_effortacceptées par ce modèle (par exemplenone,low,high). Le champ est vide quand les niveaux ne sont pas configurables.is_ready:falsesignifie qu'aucune route n'est opérationnelle pour le moment. Le modèle reste listé.lifecycle:gaoupreview.serving:hosted(les poids tournent sur Nodion) ourouted(transmis à un fournisseur).supports_decisions: le modèle répond à System One.coding_plan: Codion peut proposer ce modèle de chat. La valeur est toujourstrueoufalse. Ce champ ne désigne pas une offre de facturation.free_until: présent tant qu'une période gratuite est active sur un modèle servi uniquement par Nodion. Les prix par token affichent alors 0.
Complétions de chat
POST /v1/chat/completions accepte le corps OpenAI Chat Completions : model,
messages et les champs facultatifs que le modèle liste dans supported_sampling_parameters
et supported_features, comme tools ou response_format.
N'envoyez reasoning_effort que si reasoning_efforts n'est pas vide, et uniquement avec une valeur de cette liste.
bashcurl https://api.nodion.ai/v1/chat/completions \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<model>",
"stream": true,
"max_tokens": 512,
"messages": [
{"role": "system", "content": "Answer in one sentence."},
{"role": "user", "content": "What is an embedding?"}
]
}' Ce que la passerelle fait de la requête et de la réponse :
- Sans
max_tokens(oumax_completion_tokens), la passerelle fixemax_tokensaumax_output_lengthdu modèle. Les valeurs supérieures sont ramenées à cette limite. - Avec
"stream": true, la réponse arrive en server-sent events (lignesdata: {...}, puisdata: [DONE]). La passerelle activestream_options.include_usage, donc le dernier chunk contient normalement l'usage. Si la connexion upstream est coupée en cours de stream, un dernier chunk porte un objeterroretfinish_reason: "error", suivi dedata: [DONE]. - Le champ
modelde la réponse est l'id que vous avez envoyé. Le texte de raisonnement, quand un modèle en renvoie, se trouve dansreasoning_content.
Les PDF peuvent être intégrés directement comme blocs de contenu file avec une URI de données en base64. La passerelle convertit les
20 premières pages en images avant l'appel, donc cela ne sert qu'avec les modèles qui acceptent des images en entrée. Les références
file_id sont refusées.
json{
"role": "user",
"content": [
{"type": "text", "text": "Summarize this contract."},
{"type": "file", "file": {"file_data": "data:application/pdf;base64,JVBERi0..."}}
]
}
Facturation : tokens d'entrée et de sortie au prix du modèle, entrée en cache au prix du cache quand la route
le déclare. La réservation compte chaque octet de la requête comme un token d'entrée, plus max_tokens. Pour les requêtes
avec images ou PDF, la part d'entrée est portée à la longueur de contexte du modèle, ou à au moins 128 000 tokens
si la requête dépasse le contexte. Pendant la période gratuite d'un modèle
(free_until), les complétions de chat sur les routes hébergées sont gratuites.
Responses API
POST /v1/responses accepte le corps de l'OpenAI Responses API : model, input
(du texte ou une liste d'items) et les champs facultatifs instructions, tools,
tool_choice, parallel_tool_calls, text.format, reasoning.effort,
max_output_tokens, max_tool_calls, temperature, top_p,
top_logprobs, include et stream. La passerelle
traduit la requête en complétion de chat : les règles de la section Complétions de chat s'appliquent aussi ici :
le plafond de sortie, les reasoning_efforts autorisés, les PDF et la facturation.
bashcurl https://api.nodion.ai/v1/responses \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<model>",
"instructions": "Answer in one sentence.",
"input": "What is an embedding?"
}'
Avec "stream": true, la réponse est le flux d'événements de la Responses API, par exemple response.created,
response.output_text.delta et response.function_call_arguments.delta, qui se termine par
response.completed et son usage. Si le stream est interrompu, le dernier événement est
response.failed. Le texte de raisonnement arrive dans un item reasoning sous forme de reasoning_text.
Renvoyez cet item dans les requêtes suivantes : le raisonnement postérieur au dernier message de l'utilisateur est retransmis au modèle,
le raisonnement plus ancien uniquement avec reasoning.context: "all_turns".
La passerelle exécute elle-même web_search, via la recherche web de Nodion. Quand le
modèle lance une recherche, la passerelle récupère les résultats, les transmet au modèle et l'appelle à nouveau. La réponse contient un
item web_search_call avec la requête de recherche et les URL des sources, diffusé en streaming avec les événements
response.web_search_call.in_progress, searching et completed.
Facturation : chaque recherche est facturée comme un appel à /v1/tools/web_search, et chaque tour du modèle comme une complétion de chat.
usage est la somme de tous les tours. Une Response compte une seule fois dans la limite de requêtes de la clé. Au plus
max_tool_calls recherches par Response (10 par défaut, 20 au maximum) ; max_output_tokens couvre
l'ensemble des tours. filters.allowed_domains, user_location (ville, région, pays) et
search_context_size (5, 10 ou 20 résultats) sont pris en compte. La recherche ne renvoie que des résultats de l'index de recherche (titre,
URL, extrait) et n'ouvre aucune page, même avec external_web_access: true.
Logprobs : avec top_logprobs (jusqu'à 20) ou include: ["message.output_text.logprobs"],
ils figurent sur output_text quand le modèle les renvoie.
Avec cette configuration, Codex CLI fonctionne avec Nodion, recherche web comprise :
toml# ~/.codex/config.toml
model = "<model>"
model_provider = "nodion"
[model_providers.nodion]
name = "Nodion"
base_url = "https://api.nodion.ai/v1"
env_key = "NODION_AI_KEY"
wire_api = "responses" Différences avec OpenAI :
- Nodion ne stocke aucune réponse.
storeest ignoré et la réponse indiquestore: false. Il n'y a niprevious_response_id, niconversation, niitem_reference, niGET /v1/responses/{id}. Envoyez toute la conversation dansinput, comme le fait Codex. - Outils :
function,custom,namespaceetweb_search. Les autres outils hébergés, commefile_searchoucode_interpreter, sont refusés avec une erreur 400. - Les résultats de recherche ne sont pas stockés. Un
web_search_callprésent dans la conversation parvient au modèle sous forme d'appel accompagné d'une note, sans les anciens résultats.annotations(citations) reste vide ; les sources se trouvent dans leweb_search_call. - Les images et les fichiers contenus dans les sorties d'outils ne parviennent pas au modèle ; une note dans le texte les remplace.
- Non pris en charge (400) :
background,prompt,truncation: "auto",file_idetfile_url. Envoyez les images enimage_url(une URL ou une data URI) et les PDF eninput_fileavecfile_data.
Embeddings
POST /v1/embeddings accepte le corps OpenAI (model, input sous forme de chaîne ou
de tableau) et renvoie la réponse embeddings d'OpenAI. Pas de streaming. Facturé sur usage.prompt_tokens.
Utilisez un modèle avec kind: "embeddings".
bashcurl https://api.nodion.ai/v1/embeddings \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "<embeddings-model>", "input": ["first text", "second text"]}' Rerank
POST /v1/rerank note des documents par rapport à une query. Le paramètre facultatif
top_n limite le nombre de résultats. La réponse contient results avec index (position
dans documents) et relevance_score, ainsi que usage.prompt_tokens, sur lequel porte
la facturation. Utilisez un modèle avec kind: "rerank".
bashcurl https://api.nodion.ai/v1/rerank \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<rerank-model>",
"query": "How do I reset my password?",
"documents": ["Billing FAQ", "Account recovery guide", "Release notes"],
"top_n": 2
}' System One
POST /v1/systemone répond à des questions typées sur un état donné. Le modèle note chaque
réponse possible au lieu d'écrire du texte, donc vous recevez des probabilités, pas de la prose. Utilisez-le pour le routage,
le tri, la modération, ou comme point de contrôle avant qu'un agent n'exécute un outil. Un seul appel répond à 16 questions au maximum sur le
même état.
Les modèles avec supports_decisions: true sur /v1/models prennent en charge System One. Celui-ci tourne sur
des routes hébergées par Nodion et chez les fournisseurs qui proposent eux-mêmes System One. Si une route échoue avant d'avoir exécuté la
requête (rate limit, panne), la même requête passe à la route suivante. L'onglet Decisions du
Playground contient des exemples prêts à l'emploi.
bashcurl https://api.nodion.ai/v1/systemone \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "aleph-alpha/kolibri-1",
"state": {
"customer_tier": "enterprise",
"ticket": "My checkout page shows a blank screen after I click Pay."
},
"questions": {
"is_bug": {
"type": "noul",
"instructions": "Is the customer reporting a software defect?"
},
"team": {
"type": "choice",
"instructions": "Which team should own this ticket?",
"criteria": {
"payments": "Checkout, billing, or payment processing issues.",
"frontend": "Rendering, layout, or browser issues.",
"account": "Login, permissions, or profile issues."
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": [
"Can wait for the next release",
"Should be fixed this week",
"Blocking revenue right now"
]
}
}
}' Requête
model(obligatoire) : un modèle avecsupports_decisions.state(obligatoire) : ce sur quoi portent les questions. Une chaîne, un objet, un tableau ounull.questions(obligatoire) : un objet de 1 à 16 entrées. La clé est le nom que vous donnez à la question (jusqu'à 128 caractères) et revient comme clé dansanswers.
Chaque question a un type, des instructions facultatives et des criteria qui
dépendent du type. Les valeurs de ces deux derniers champs peuvent être une chaîne, un objet ou un tableau ;
null est accepté partout sauf pour les niveaux de score.
noul: une question oui/non.criteriaest facultatif et ne peut avoir que les cléstrueetfalse. Unnoulnécessite desinstructionsnon vides ou au moins un critère non vide.choice: choisir une étiquette.criteriaassocie de 1 à 26 étiquettes à une valeur ; les chaînes vides sont refusées. Les étiquettes doivent être uniques, sans tenir compte de la casse, et faire au plus 256 caractères.score: noter sur une échelle.criteriaest un tableau de 2 à 10 niveaux non vides, du plus bas au plus haut. Les index de niveau commencent à 0.
Les champs inconnus sont refusés. Le corps peut atteindre 512 KiB, et l'état ainsi que la plus grande question doivent tenir ensemble dans le contexte du modèle.
Réponse
json{
"model": "aleph-alpha/kolibri-1",
"answers": {
"is_bug": {"type": "noul", "noul": 0.91},
"team": {
"type": "choice",
"choice": "payments",
"confidence": 0.78,
"probabilities": {"payments": 0.82, "frontend": 0.15, "account": 0.03}
},
"urgency": {
"type": "score",
"score": 1.5,
"confidence": 0.6,
"legend": {
"0": "Can wait for the next release",
"1": "Should be fixed this week",
"2": "Blocking revenue right now"
},
"probabilities": {"0": 0.1, "1": 0.3, "2": 0.6}
}
},
"usage": {"input_tokens": 412, "output_tokens": 0}
} noul: la probabilité que la réponse soittrue, de 0 à 1.choice:choiceest l'étiquette la plus probable.probabilitiescontient toutes les étiquettes, avec une somme de 1, etconfidenceest une valeur de 0 à 1.score:scoreest la moyenne des index de niveau pondérée par les probabilités (de 0 jusqu'au nombre de niveaux moins 1).probabilitiesetlegendont pour clés les index de niveau ;legendassocie chaque index à la description d'un niveau.confidenceest une valeur de 0 à 1.modelest le modèle qui a répondu.usage.output_tokensvaut toujours 0.
Les valeurs de l'exemple de réponse sont données à titre indicatif.
Facturation
Seuls les tokens d'entrée sont facturés, au tarif d'entrée du modèle. Le modèle lit l'état une fois par question :
usage.input_tokens augmente avec le nombre de questions. Avant l'appel, un montant correspondant à
(octets de l'état + octets de toutes les questions + 4 096) × le nombre de questions, au tarif des tokens d'entrée,
est réservé sur le solde. La requête est ensuite facturée selon usage.input_tokens, jamais au-delà de la réservation. Les requêtes en échec ne sont pas
facturées ; si vous vous déconnectez après que le modèle a répondu, ses tokens d'entrée sont facturés. Les périodes gratuites s'appliquent comme
pour le chat.
Erreurs
System One utilise son propre corps d'erreur : {"detail": "message"} et, pour une erreur 422, une liste
d'items loc / msg / type qui désignent le champ concerné.
json{
"detail": [
{"loc": ["body", "questions", "team", "criteria"], "msg": "choice accepts 1 to 26 criteria", "type": "too_long"}
]
} - 401 : clé absente ou invalide.
- 402 : la facturation a refusé la requête (solde, limites de dépenses, ou requête impossible à tarifer). Les motifs sont ceux des codes 402, ici uniquement sous forme de texte dans
detail. - 404 :
model not found, y compris pour les modèles sanssupports_decisions. - 422 : corps invalide, corps de plus de 512 KiB, état et questions dépassant le contexte, ou requête refusée par le modèle.
- 429 : une limite de la clé a été atteinte (
Retry-After: 5), ou toutes les routes de fournisseurs testées ont atteint leur rate limit (leRetry-Afterdu fournisseur, 60 secondes au maximum). - 502 : le modèle n'a pas réussi à répondre.
- 503 : aucune route opérationnelle, aucune qui corresponde aux paramètres de confidentialité du projet, ou les paramètres n'ont pas pu être chargés.
- 529 : toutes les routes du modèle sont à pleine capacité.
Retry-After: 5.
OCR
POST /v1/ocr suit le format Mistral OCR. Envoyez le fichier inline sous forme de data URI en base64 ;
les URL distantes sont refusées. PDF, PNG, JPEG et WebP sont acceptés.
bashcurl https://api.nodion.ai/v1/ocr \
-H "Authorization: Bearer $NODION_AI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral/mistral-ocr-4-1",
"document": {
"type": "document_url",
"document_url": "data:application/pdf;base64,JVBERi0..."
}
}' model: un modèle OCR du catalogue public (kind: "ocr").document:{"type": "document_url", "document_url": "data:..."}ou{"type": "image_url", "image_url": "data:..."}.pages(facultatif) : index des pages à lire, à partir de 0. Tous les modèles OCR ne le prennent pas en charge ; les modèles OCR hébergés etfirecrawl/pdf-inspectorrépondent 400.include_image_base64(facultatif) : renvoie les images intégrées en base64. Tous les modèles OCR ne renvoient pas d'images ; certains répondent toujours avec une listeimagesvide.
La réponse contient pages (chacune avec index, markdown et
images) et usage_info.pages_processed. Facturé par page traitée. La réservation couvre
tout le document, et les documents qui dépassent le max_pages du modèle sont refusés.
firecrawl/pdf-inspector ne lit que les PDF générés numériquement. Une image reçoit une erreur 422 ; un PDF avec des
pages scannées provoque une erreur 422 avec code: "pages_need_ocr" et les pages concernées dans
pages_needing_ocr.
Erreurs et limites
Tous les endpoints sauf System One renvoient les erreurs dans l'enveloppe OpenAI :
json{
"error": {
"message": "insufficient AI balance. Top up in the AI Billing tab.",
"type": "error",
"code": "empty_balance"
}
} message est toujours présent. type, ainsi que la présence de code, varient selon
l'endpoint : basez-vous d'abord sur le statut HTTP. Les requêtes de chat, d'embeddings, de rerank et d'outils web placent les
codes 402 dans code. Quand la route du modèle répond au chat, aux embeddings ou au
rerank avec une erreur HTTP, le corps contient aussi request_id. L'en-tête X-Request-ID
est toujours présent.
- 400 : JSON invalide,
modelmanquant, ou modèle d'un type inadapté à l'endpoint (par exemple un modèle OCR pour le chat). Un corps de plus de 25 MiB qui atteint le processus de l'API renvoierequest body exceeds 25 MiB. - 401 : voir Authentification.
- 402 : le solde a refusé la requête ; voir les codes ci-dessous.
- 404 :
model not found, ou un endpoint qui n'existe pas. - 413 : l'hôte public a refusé un corps de plus de 25 MiB avant l'exécution de l'API.
- 429 : une limite de la clé a été atteinte, ou le modèle est surchargé. Respectez
Retry-Afterquand il est envoyé. - 502 : la route du modèle a échoué. Réessayez plus tard.
- 503 : aucune route opérationnelle pour le modèle, aucune qui corresponde aux paramètres de confidentialité du projet (onglet Settings), ou les paramètres n'ont pas pu être chargés.
Codes 402. Les requêtes de chat, d'embeddings, de rerank et d'outils web les envoient dans code. L'OCR, l'audio et la génération d'images
n'envoient que le message, et System One l'envoie dans detail.
empty_balance: le solde IA disponible ne couvre pas la réservation de cette requête. Rechargez-le dans l'onglet Billing, ou activez la recharge automatique.daily_quota: les dépenses du jour sur cette clé, plus ses réservations en cours, plus cette requête dépasseraient la limite de dépenses quotidienne de la clé.month_quota: les dépenses du mois, plus les réservations en cours, plus cette requête dépasseraient la limite de dépenses mensuelle que vous avez définie dans l'onglet Billing.usage_limit: les dépenses du mois, plus les réservations en cours, plus cette requête dépasseraient le plafond mensuel de votre palier d'usage. L'onglet Billing affiche le palier et le moment où le suivant s'applique.pricing_unavailableetreserve_failed: la requête n'a pas pu être tarifée ou réservée. Réessayez, puis contactez le support en indiquant l'id de la requête.
Limites par défaut par clé :
- 600 requêtes par minute
- 4 000 000 tokens par minute (chat, embeddings, rerank et System One)
- 20 requêtes simultanées
- 25 MiB de corps de requête pour le chat, les embeddings, le rerank, l'OCR, l'audio et les images. Outils : 1 MiB. System One : 512 KiB.
Pour le chat, les embeddings et le rerank, une erreur 429 envoie Retry-After: 5 pour le débit de requêtes et en cas de
surcharge, 10 pour le débit de tokens et 2 pour la concurrence. System One envoie toujours
Retry-After: 5. La création d'une voix envoie Retry-After quand ses propres limites sont atteintes (trop
d'uploads en cours, ou plus de dix tentatives de création par heure). Les autres erreurs 429 sur l'OCR, l'audio, l'image, les outils web et
les voix n'en envoient pas ; attendez quelques secondes avant de réessayer. Contactez le support si vous avez besoin de limites plus élevées.