AI-API-Referenz

Jeder Endpoint auf api.nodion.ai/v1, mit Limits und Fehlern.

Basis-URL: https://api.nodion.ai/v1. Die API folgt der OpenAI-Form, OpenAI-SDKs funktionieren also, wenn du sie auf diese Basis-URL zeigst. Keys, Wallet und Dashboard-Tabs stehen unter AI Inference.

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)

Authentifizierung

Einen Inference-Key (nodion_ai_…) als Bearer-Token auf jedem Request schicken. Plattform-Keys (nodion_…) funktionieren hier nicht. GET /v1/models ist der einzige Call, der keinen Key braucht.

httpAuthorization: Bearer nodion_ai_…

Ein abgelehnter Key antwortet 401 mit einer dieser Messages:

  • missing bearer token
  • invalid api key
  • api key expired
  • account disabled
  • account under review

Jede Antwort trägt einen Header X-Request-ID. Den dem Support nennen.

JSON-Request-Bodies dürfen bis 1 MiB groß sein (System One 512 KiB). Base64 macht ein Drittel extra, eine Datei inline in JSON, etwa ein Bild, ein PDF oder ein OCR-Dokument, kann also etwa 750 KB sein. Multipart-Uploads an /v1/audio/transcriptions und /v1/audio/voices dürfen bis 25 MiB sein, mit Transkriptionsdateien bis 20 MiB und Voice-Sample-Dateien bis 10 MiB (11 MiB für das ganze Formular).

Endpoints

Endpoint Was es tut Abrechnung nach
GET /v1/modelsToken-bezahlte Modelle listenKostenlos
POST /v1/chat/completionsChat, Tools, Structured OutputInput- und Output-Tokens
POST /v1/embeddingsVektor-EmbeddingsInput-Tokens
POST /v1/rerankDokumente gegen eine Query rankenInput-Tokens
POST /v1/systemoneSystem One: typisierte Entscheidungen mit WahrscheinlichkeitenInput-Tokens
POST /v1/ocrDokument- und Bild-OCRSeiten
POST /v1/audio/transcriptionsSprache zu TextAudio-Sekunden
GET /v1/audio/transcriptions/realtime (WebSocket)Echtzeit Sprache zu TextAudio-Sekunden
POST /v1/audio/speechText zu SpracheZeichen
GET, POST /v1/audio/voicesGeklonte Voices listen und anlegenKostenlos
GET, DELETE /v1/audio/voices/{id}Eine geklonte Voice lesen oder löschenKostenlos
POST /v1/images/generationsBildgenerierungBilder
POST /v1/tools/web_search, web_news, web_fetch, web_images, web_videos, web_places, web_maps, web_shopping, web_lensWeb-ToolsCalls, plus jede Seite, die ein web_search fetcht

Audio, Bilder und Tools stehen mit Beispielen unter AI Inference. Der Rest folgt hier.

Vor einem Call hält das Wallet eine Obergrenze der Kosten. Der Request wird dann auf den gemeldeten Usage abgerechnet, nie über dem Hold, der Rest wird freigegeben. Meldet eine erfolgreiche Antwort keinen Usage, wird der volle Hold berechnet. Eine Realtime-Transkription-Session hält max_audio_seconds des Modells (1.800 Sekunden, wenn das Modell keins setzt), das Wallet muss also eine volle Session im Voraus decken.

Modelle

GET /v1/models gibt {"object": "list", "data": [...]} zurück und listet Chat-, Embeddings- und Rerank-Modelle. OCR, Speech, Bild und Tool-Modelle stehen nicht darin; der öffentliche Katalog unter https://api.nodion.com/v2/public/ai/models listet jede Art. Nützliche Felder pro Modell:

  • id: der Wert für model in Requests.
  • kind: chat, embeddings oder rerank.
  • context_length und max_output_length in Tokens.
  • pricing: USD pro Token als Dezimalstrings. pricing_eur hat die EUR-Preise.
  • supported_sampling_parameters und supported_features (zum Beispiel tools, json_mode, structured_outputs, reasoning).
  • reasoning_efforts: die Werte für reasoning_effort, die dieses Modell akzeptiert (zum Beispiel none, low, high). Leer, wenn Stages nicht konfigurierbar sind.
  • is_ready: false heißt, gerade ist keine Route healthy. Das Modell bleibt gelistet.
  • lifecycle: ga oder preview. serving: hosted (die Weights laufen auf Nodion) oder routed (an einen Provider weitergeleitet).
  • supports_decisions: das Modell beantwortet System One.
  • coding_plan: Codion kann dieses Chat-Modell anbieten. Immer true oder false. Das ist nicht der Abrechnungs-Coding-Plan.
  • free_until: gesetzt, solange ein Free-Fenster auf einem nur von Nodion bedienten Modell aktiv ist. Die Token-Preise lesen dann 0.

Chat Completions

POST /v1/chat/completions nimmt den OpenAI-Chat-Completions-Body: model, messages und die optionalen Felder, die das Modell in supported_sampling_parameters und supported_features listet, etwa tools oder response_format. reasoning_effort nur schicken, wenn reasoning_efforts nicht leer ist, und nur einen Wert aus dieser 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?"}
    ]
  }'

Was das Gateway mit Request und Antwort macht:

  • Ohne max_tokens (oder max_completion_tokens) setzt das Gateway max_tokens auf max_output_length des Modells. Größere Werte werden darauf gesenkt.
  • Mit "stream": true ist die Antwort Server-Sent Events (Zeilen data: {...}, dann data: [DONE]). Das Gateway setzt stream_options.include_usage, der letzte Chunk trägt also normalerweise Usage. Bricht die Upstream-Verbindung mitten im Stream, trägt ein letzter Chunk ein Objekt error und finish_reason: "error", gefolgt von data: [DONE].
  • Das Feld model in der Antwort ist die ID, die du geschickt hast. Reasoning-Text, wenn ein Modell ihn zurückgibt, steht in reasoning_content.

PDFs können inline als file-Content-Block mit einer Base64-Data-URI kommen. Das Gateway rendert die ersten 20 Seiten zu Bildern vor dem Call, das hilft also nur bei Modellen mit Bild-Input. Referenzen auf file_id werden abgelehnt.

json{
  "role": "user",
  "content": [
    {"type": "text", "text": "Summarize this contract."},
    {"type": "file", "file": {"file_data": "data:application/pdf;base64,JVBERi0..."}}
  ]
}

Abrechnung: Input- und Output-Tokens zum Modellpreis, gecachter Input zum Cache-Preis, wo die Route ihn meldet. Der Hold zählt jedes Request-Byte als Input-Token, plus max_tokens. Bei Requests mit Bildern oder PDFs wird der Input-Teil auf die Context-Length des Modells angehoben, oder auf mindestens 128.000 Tokens, wenn der Request größer als der Context ist. Im Free-Fenster eines Modells (free_until) sind Chat Completions auf gehosteten Routes kostenlos.

Embeddings

POST /v1/embeddings nimmt den OpenAI-Body (model, input als String oder Array) und gibt die OpenAI-Embeddings-Antwort zurück. Kein Streaming. Abrechnung über usage.prompt_tokens. Ein Modell mit kind: "embeddings" nutzen.

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 scored documents gegen eine query. Optionales top_n begrenzt die Ergebnisse. Die Antwort hat results mit index (Position in documents) und relevance_score, plus usage.prompt_tokens, worüber abgerechnet wird. Ein Modell mit kind: "rerank" nutzen.

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 beantwortet typisierte Fragen zu einem Stück State. Das Modell scored jede mögliche Antwort statt Text zu schreiben, du bekommst also Wahrscheinlichkeiten zurück, keinen Prosa. Nutz es für Routing, Triage, Moderation oder als Gate, bevor ein Agent ein Tool ausführt. Ein Call beantwortet bis zu 16 Fragen zum selben State.

Modelle mit supports_decisions: true auf /v1/models bedienen es. System One läuft nur auf Nodion-gehosteten Routes, nie auf gerouteten Providern. Der Tab Decisions im Playground hat fertige Beispiele.

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"
        ]
      }
    }
  }'

Request

  • model (pflicht): ein Modell mit supports_decisions.
  • state (pflicht): worum die Fragen gehen. Ein String, Objekt, Array oder null.
  • questions (pflicht): ein Objekt mit 1 bis 16 Einträgen. Der Key ist dein Name für die Frage (bis 128 Zeichen) und kommt als Key in answers zurück.

Jede Frage hat einen type, optionale instructions und criteria, die vom Type abhängen. Instructions und Criteria-Werte können String, Objekt oder Array sein; null ist überall erlaubt außer bei Score-Levels.

  • noul: eine Ja/Nein-Frage. criteria ist optional und darf nur die Keys true und false haben. Ein noul braucht nicht-leere instructions oder mindestens ein nicht-leeres Criterion.
  • choice: ein Label wählen. criteria mappt 1 bis 26 Labels auf einen Wert; leere Strings werden abgelehnt. Labels müssen unique sein, ohne Groß/Klein, und bis 256 Zeichen.
  • score: auf einer Skala bewerten. criteria ist ein Array von 2 bis 10 nicht-leeren Levels, niedrigstes zuerst. Level-Indexes starten bei 0.

Unbekannte Felder werden abgelehnt. Der Body darf bis 512 KiB sein, und State plus die größte Frage müssen in den Context des Modells passen.

Response

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: die Wahrscheinlichkeit, dass die Antwort true ist, von 0 bis 1.
  • choice: choice ist das wahrscheinlichste Label, probabilities hat jedes Label und summiert auf 1, confidence ist ein Wert von 0 bis 1.
  • score: score ist der wahrscheinlichkeitsgewichtete Mittelwert der Level-Indexes (0 bis Anzahl der Levels minus 1). probabilities und legend sind nach Level-Index keyed; legend mappt jeden Index auf eine Level-Beschreibung. confidence ist ein Wert von 0 bis 1.
  • model ist das Modell, das geantwortet hat. usage.output_tokens ist immer 0.

Die Werte in der Beispielantwort sind illustrativ.

Abrechnung

Nur Input-Tokens werden berechnet, zum Input-Preis des Modells. Das Modell liest den State einmal pro Frage, also wächst usage.input_tokens mit der Zahl der Fragen. Vor dem Call hält das Wallet (Bytes des State + Bytes aller Fragen + 4.096) × die Zahl der Fragen als Input-Tokens, und der Request wird auf usage.input_tokens abgerechnet, nie über dem Hold. Requests, die scheitern, werden nicht berechnet; trennst du nach der Antwort des Modells, werden seine Input-Tokens berechnet. Free-Fenster gelten wie bei Chat.

Fehler

System One nutzt einen eigenen Error-Body: {"detail": "message"}, und bei 422 eine Liste von Items loc / msg / type, die auf das Feld zeigen.

json{
  "detail": [
    {"loc": ["body", "questions", "team", "criteria"], "msg": "choice accepts 1 to 26 criteria", "type": "too_long"}
  ]
}
  • 401: fehlender oder ungültiger Key.
  • 402: Billing hat den Request abgelehnt: Balance, Spend-Limits oder der Request ließ sich nicht preisen. Die Gründe sind die der 402-Codes, hier nur als detail-Text.
  • 404: model not found, auch für Modelle ohne supports_decisions.
  • 422: ungültiger Body, Body über 512 KiB, State und Fragen über dem Context, oder das Modell hat den Request abgelehnt.
  • 429: ein Key-Limit wurde getroffen. Retry-After: 5.
  • 502: das Modell hat nicht geantwortet.
  • 503: keine healthy Route, keine die zu den Privacy-Settings des Projekts passt, oder die Settings ließen sich nicht laden.
  • 529: jede Route für das Modell ist voll. Retry-After: 5.

OCR

POST /v1/ocr folgt der Mistral-OCR-Form. Die Datei inline als Base64-Data-URI schicken; Remote-URLs werden abgelehnt. PDF, PNG, JPEG und WebP gehen.

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: ein OCR-Modell aus dem öffentlichen Katalog (kind: "ocr").
  • document: {"type": "document_url", "document_url": "data:..."} oder {"type": "image_url", "image_url": "data:..."}.
  • pages (optional): zu lesende Seiten-Indexes, startend bei 0. Nicht jedes OCR-Modell unterstützt das; gehostete OCR-Modelle und firecrawl/pdf-inspector antworten 400.
  • include_image_base64 (optional): eingebettete Bilder als Base64 zurückgeben. Nicht jedes OCR-Modell gibt Bilder zurück; manche antworten immer mit einer leeren Liste images.

Die Antwort hat pages (jede mit index, markdown und images) und usage_info.pages_processed. Abrechnung pro verarbeiteter Seite. Der Hold deckt das ganze Dokument, und Dokumente über max_pages des Modells werden abgelehnt. firecrawl/pdf-inspector liest nur digital erzeugte PDFs. Ein Bild antwortet 422; ein PDF mit gescannten Seiten antwortet 422 mit code: "pages_need_ocr" und den betroffenen Seiten in pages_needing_ocr.

Fehler und Limits

Jeder Endpoint außer System One antwortet Fehler im OpenAI-Envelope:

json{
  "error": {
    "message": "insufficient AI balance. Top up in the AI Billing tab.",
    "type": "error",
    "code": "empty_balance"
  }
}

message ist immer da. type und ob code gesetzt ist, variieren je Endpoint, also zuerst nach HTTP-Status branchen. Chat, Embeddings, Rerank und die Web-Tools legen die 402-Codes in code. Wenn die Route des Modells Chat, Embeddings oder Rerank mit einem HTTP-Fehler beantwortet, trägt der Body außerdem request_id. Der Header X-Request-ID ist immer da.

  • 400: ungültiges JSON, fehlendes model oder ein Modell der falschen Art für den Endpoint (zum Beispiel ein OCR-Modell auf Chat). Ein Body über 25 MiB, der den API-Prozess erreicht, nutzt request body exceeds 25 MiB.
  • 401: siehe Authentifizierung.
  • 402: das Wallet hat den Request abgelehnt; siehe die Codes unten.
  • 404: model not found, oder ein Endpoint, der nicht existiert.
  • 413: der öffentliche Host hat einen Body größer als 25 MiB abgelehnt, bevor die API lief.
  • 429: ein Key-Limit wurde getroffen, oder das Modell ist überlastet. Retry-After achten, wo es geschickt wird.
  • 502: die Route des Modells ist fehlgeschlagen. Später retryen.
  • 503: keine healthy Route für das Modell, keine die zu den Privacy-Settings des Projekts passt (Tab Settings), oder die Settings ließen sich nicht laden.

402-Codes. Chat, Embeddings, Rerank und die Web-Tools schicken sie in code. OCR, Audio und Bild schicken nur die Message, System One als detail.

  • empty_balance: das verfügbare AI-Guthaben deckt den Hold für diesen Request nicht. Im Tab Billing aufladen oder Auto-Top-up einschalten.
  • daily_quota: der heutige Spend auf diesem Key plus offene Holds plus dieser Request würde das tägliche Spend-Limit des Keys überschreiten.
  • month_quota: der Spend dieses Monats plus offene Holds plus dieser Request würde das monatliche Spend-Limit überschreiten, das du im Tab Billing gesetzt hast.
  • usage_limit: der Spend dieses Monats plus offene Holds plus dieser Request würde die monatliche Cap deiner Usage-Tier überschreiten. Der Tab Billing zeigt die Tier und wann die nächste gilt.
  • pricing_unavailable und reserve_failed: der Request ließ sich nicht preisen oder halten. Retryen, dann Support mit der Request-ID kontaktieren.

Default-Limits pro Key:

  • 600 Requests pro Minute
  • 4.000.000 Tokens pro Minute (Chat, Embeddings, Rerank und System One)
  • 20 gleichzeitige Requests
  • 25 MiB Request-Body bei Chat, Embeddings, Rerank, OCR, Audio und Bildern. Tools sind 1 MiB. System One ist 512 KiB.

Bei Chat, Embeddings und Rerank schickt ein 429 Retry-After: 5 für die Request-Rate und für Overload, 10 für die Token-Rate und 2 für Concurrency. System One schickt immer Retry-After: 5. Eine Voice anzulegen schickt Retry-After, wenn eigene Limits greifen (zu viele Uploads parallel, oder mehr als zehn Create-Versuche pro Stunde). Andere 429s bei OCR, Audio, Bild, den Web-Tools und Voices schicken keins; ein paar Sekunden warten, dann retryen. Support kontaktieren, wenn du höhere Limits brauchst.

Gib deinem Agenten eine Cloud.

Bis zu 15 € Guthaben beim Registrieren.

Weiter mit GitHub

oder per E-Mail

Bleib auf dem Laufenden.

Produktnews, kein Spam. Jederzeit abbestellen.