Dokumentacja API AI
Wszystkie endpointy na api.nodion.ai/v1, z limitami i błędami.
Bazowy URL: https://api.nodion.ai/v1. API ma format zgodny z OpenAI, więc SDK OpenAI działają,
gdy ustawisz w nich ten bazowy URL. Klucze, saldo i zakładki w dashboardzie opisuje strona
AI Inference. Modele, dostawców i ceny znajdziesz w katalogu modeli.
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) Uwierzytelnianie
W każdym żądaniu wysyłaj klucz API do inferencji (nodion_ai_…) jako token Bearer. Klucze platformy
(nodion_…) tu nie działają. GET /v1/models to jedyne wywołanie, które nie wymaga klucza.
httpAuthorization: Bearer nodion_ai_… Odrzucony klucz powoduje odpowiedź 401 z jednym z poniższych komunikatów:
missing bearer tokeninvalid api keyapi key expiredaccount disabledaccount under review
Każda odpowiedź zawiera nagłówek X-Request-ID. Podaj go, gdy kontaktujesz się z supportem.
Treść żądania w formacie JSON może mieć do 25 MiB (narzędzia 1 MiB, System One 512 KiB). Base64 zwiększa rozmiar o jedną trzecią,
więc plik wysłany bezpośrednio w JSON, np. obraz, PDF lub dokument do OCR, może mieć około 18 MiB. Pliki przesyłane w żądaniach multipart do
/v1/audio/transcriptions i /v1/audio/voices mogą mieć do 25 MiB, przy czym pliki
do transkrypcji mogą mieć do 20 MiB, a pliki z próbkami głosu do 10 MiB (11 MiB na cały
formularz).
Endpointy
| Endpoint | Do czego służy | Rozliczane według |
|---|---|---|
GET /v1/models | Lista modeli rozliczanych za tokeny | Bezpłatnie |
POST /v1/chat/completions | Czat, narzędzia, ustrukturyzowane wyjście | Tokeny wejściowe i wyjściowe |
POST /v1/responses | OpenAI Responses API, np. dla Codex | Tokeny wejściowe i wyjściowe |
POST /v1/embeddings | Embeddingi wektorowe | Tokeny wejściowe |
POST /v1/rerank | Ocena trafności dokumentów względem zapytania | Tokeny wejściowe |
POST /v1/systemone | System One: decyzje określonego typu z prawdopodobieństwami | Tokeny wejściowe |
POST /v1/ocr | OCR dokumentów i obrazów | Strony |
POST /v1/audio/transcriptions | Zamiana mowy na tekst | Sekundy audio |
GET /v1/audio/transcriptions/realtime (WebSocket) | Zamiana mowy na tekst w czasie rzeczywistym | Sekundy audio |
POST /v1/audio/speech | Zamiana tekstu na mowę | Znaki |
GET, POST /v1/audio/voices | Lista i tworzenie sklonowanych głosów | Bezpłatnie |
GET, DELETE /v1/audio/voices/{id} | Odczyt lub usunięcie jednego sklonowanego głosu | Bezpłatnie |
POST /v1/images/generations | Generowanie obrazów | Obrazy |
POST /v1/tools/web_search, web_news, web_fetch, web_images, web_videos, web_places, web_maps, web_shopping, web_lens | Narzędzia webowe | Wywołania oraz każda strona pobrana przez web_search |
Audio, obrazy i narzędzia są opisane z przykładami na stronie AI Inference. Pozostałe endpointy opisujemy poniżej.
Przed wywołaniem na saldzie blokowana jest kwota odpowiadająca maksymalnemu kosztowi żądania. Żądanie jest potem rozliczane według
zgłoszonego zużycia, nigdy powyżej blokady, a niewykorzystana część zostaje zwolniona. Jeśli udana odpowiedź nie zgłasza zużycia, pobierana
jest cała zablokowana kwota. Sesja transkrypcji w czasie rzeczywistym blokuje max_audio_seconds modelu
(1 800 sekund, jeśli model go nie ustawia), więc saldo musi z góry pokryć całą sesję.
Modele
GET /v1/models zwraca {"object": "list", "data": [...]} i zawiera modele czatu,
embeddingów i rerankingu. Nie ma tam modeli OCR, mowy, obrazów ani narzędzi; publiczny katalog pod adresem
https://api.nodion.com/v2/public/ai/models zawiera wszystkie rodzaje. Przydatne pola każdego modelu:
id: wartość polamodelw żądaniach.kind:chat,embeddingslubrerank.context_lengthimax_output_lengthw tokenach.pricing: ceny w USD za token jako ciągi dziesiętne.pricing_eurzawiera ceny w EUR.supported_sampling_parametersisupported_features(np.tools,json_mode,structured_outputs,reasoning).reasoning_efforts: wartościreasoning_effort, które akceptuje ten model (np.none,low,high). Pusta lista oznacza, że poziomów nie można konfigurować.is_ready:falseoznacza, że obecnie żadna trasa nie jest sprawna. Model pozostaje na liście.lifecycle:galubpreview.serving:hosted(wagi modelu działają na Nodion) lubrouted(przekazywane do dostawcy).supports_decisions: model obsługuje System One.coding_plan: Codion może oferować ten model czatu. Zawszetruelubfalse. Nie ma to związku z rozliczanym planem (coding plan).free_until: ustawione, dopóki na modelu obsługiwanym wyłącznie przez Nodion trwa okres bezpłatny. Ceny tokenów wynoszą wtedy 0.
Chat completions
POST /v1/chat/completions przyjmuje treść żądania w formacie OpenAI Chat Completions: model,
messages oraz opcjonalne pola, które model wymienia w supported_sampling_parameters
i supported_features, takie jak tools czy response_format.
Wysyłaj reasoning_effort tylko wtedy, gdy reasoning_efforts nie jest puste, i tylko z wartością z tej listy.
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?"}
]
}' Jak bramka AI obsługuje żądanie i odpowiedź:
- Bez
max_tokens(lubmax_completion_tokens) bramka AI ustawiamax_tokensnamax_output_lengthmodelu. Większe wartości są ograniczane do tej wartości. - Przy
"stream": trueodpowiedź przychodzi jako server-sent events (liniedata: {...}, potemdata: [DONE]). Bramka AI ustawiastream_options.include_usage, więc ostatni fragment odpowiedzi zwykle zawiera zużycie. Jeśli połączenie z dostawcą zerwie się w trakcie przesyłania, ostatni fragment zawiera obiekterrorifinish_reason: "error", a po nim przychodzidata: [DONE]. - Pole
modelw odpowiedzi zawiera identyfikator z żądania. Tekst rozumowania (reasoning), jeśli model go zwraca, znajduje się wreasoning_content.
PDF-y możesz wysłać bezpośrednio jako blok treści file z data URI w base64. Przed wywołaniem bramka AI renderuje
pierwsze 20 stron do obrazów, więc ma to sens tylko w modelach z wejściem obrazowym. Odwołania file_id
są odrzucane.
json{
"role": "user",
"content": [
{"type": "text", "text": "Summarize this contract."},
{"type": "file", "file": {"file_data": "data:application/pdf;base64,JVBERi0..."}}
]
}
Rozliczenie: tokeny wejściowe i wyjściowe po cenie modelu, wejście z cache po cenie cache, jeśli trasa je zgłasza.
Blokada liczy każdy bajt żądania jako token wejściowy, plus max_tokens. Dla żądań z obrazami lub PDF-ami
część wejściowa jest podnoszona do długości kontekstu modelu albo do co najmniej 128 000 tokenów, gdy żądanie
jest większe niż kontekst. W okresie bezpłatnym modelu (free_until) chat completions na trasach
hostowanych są bezpłatne.
Responses API
POST /v1/responses przyjmuje treść żądania w formacie OpenAI Responses API: model, input
(tekst lub lista elementów) oraz opcjonalne instructions, tools,
tool_choice, parallel_tool_calls, text.format, reasoning.effort,
max_output_tokens, max_tool_calls, temperature, top_p,
top_logprobs, include i stream. Bramka AI
przekształca żądanie w chat completion, więc wszystko z sekcji o chat completions obowiązuje także tutaj:
limit wyjścia, dozwolone reasoning_efforts, PDF-y i rozliczenia.
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?"
}'
Przy "stream": true odpowiedź to strumień zdarzeń Responses API, np. response.created,
response.output_text.delta i response.function_call_arguments.delta, zakończony
response.completed z jego usage. Jeśli stream się zerwie, ostatnim zdarzeniem jest
response.failed. Tekst rozumowania przychodzi w elemencie reasoning jako reasoning_text.
Odsyłaj ten element w kolejnych żądaniach: rozumowanie od ostatniej wiadomości użytkownika wraca do modelu,
starsze tylko przy reasoning.context: "all_turns".
Bramka AI samodzielnie wykonuje web_search przez wyszukiwanie w sieci Nodion. Gdy
model wyszukuje, bramka AI pobiera wyniki, przekazuje je modelowi i wywołuje go ponownie. Odpowiedź zawiera
element web_search_call z zapytaniem i adresami URL źródeł, przesyłany w streamie ze zdarzeniami
response.web_search_call.in_progress, searching i completed.
Rozliczenie: każde wyszukiwanie jak wywołanie /v1/tools/web_search, każda runda modelu jak chat completion,
a usage to suma wszystkich rund. Jedna odpowiedź Responses API liczy się raz do limitu żądań klucza. Najwyżej
max_tool_calls wyszukiwań na odpowiedź (domyślnie 10, maksymalnie 20); max_output_tokens obejmuje
wszystkie rundy łącznie. filters.allowed_domains, user_location (miasto, region, kraj) i
search_context_size (5, 10 lub 20 wyników) są uwzględniane. Wyszukiwanie zwraca tylko wyniki z indeksu (tytuł,
URL, fragment) i nie otwiera żadnych stron, także przy external_web_access: true.
Logprobs: przy top_logprobs (do 20) lub include: ["message.output_text.logprobs"]
pojawiają się w output_text, jeśli model je zwraca.
Z tą konfiguracją Codex CLI działa z Nodion, łącznie z wyszukiwaniem w sieci:
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" Różnice względem OpenAI:
- Nodion nie przechowuje odpowiedzi.
storejest ignorowane, a odpowiedź zgłaszastore: false. Nie maprevious_response_id,conversation,item_referenceaniGET /v1/responses/{id}. Wysyłaj całą rozmowę winput, tak jak robi to Codex. - Narzędzia:
function,custom,namespaceiweb_search. Inne narzędzia hostowane, takie jakfile_searchczycode_interpreter, są odrzucane z kodem 400. - Wyniki wyszukiwania nie są przechowywane.
web_search_callw rozmowie trafia do modelu jako wywołanie z notatką, bez dawnych wyników.annotations(cytowania) pozostają puste; źródła są wweb_search_call. - Obrazy i pliki w wynikach narzędzi nie trafiają do modelu; zastępuje je notatka w tekście.
- Nieobsługiwane (400):
background,prompt,truncation: "auto",file_idifile_url. Obrazy wysyłaj jakoimage_url(URL lub data URI), a PDF-y jakoinput_filezfile_data.
Embeddings
POST /v1/embeddings przyjmuje treść żądania w formacie OpenAI (model, input jako string lub
tablica) i zwraca odpowiedź embeddings w formacie OpenAI. Bez streamingu. Rozliczane według usage.prompt_tokens.
Użyj modelu z 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 ocenia documents względem query. Opcjonalne
top_n ogranicza liczbę wyników. Odpowiedź zawiera results z index (pozycja
w documents) i relevance_score oraz usage.prompt_tokens, według którego
naliczana jest opłata. Użyj modelu z 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 odpowiada na pytania określonego typu dotyczące danego stanu. Zamiast generować opis, model ocenia każdą
możliwą odpowiedź, więc otrzymujesz prawdopodobieństwa. Używaj go do routingu, triażu, moderacji albo
jako punktu kontrolnego, zanim agent uruchomi narzędzie. Jedno wywołanie odpowiada na maksymalnie 16 pytań o ten
sam stan.
Modele z supports_decisions: true na /v1/models obsługują System One. System One działa na
trasach hostowanych przez Nodion i u dostawców, którzy sami oferują System One. Jeśli trasa zawiedzie, zanim wykona
żądanie (rate limit, awaria), to samo żądanie przechodzi do następnej trasy. Zakładka Decisions w
Playground zawiera gotowe przykłady.
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"
]
}
}
}' Żądanie
model(wymagane): model zsupports_decisions.state(wymagane): to, czego dotyczą pytania. String, obiekt, tablica lubnull.questions(wymagane): obiekt z 1 do 16 wpisami. Klucz to Twoja nazwa pytania (do 128 znaków); wraca on jako klucz wanswers.
Każde pytanie ma type, opcjonalne instructions oraz criteria zależne
od typu. Wartości instrukcji i kryteriów mogą być ciągiem znaków, obiektem lub tablicą;
null jest dozwolony wszędzie poza poziomami score.
noul: pytanie tak/nie.criteriajest opcjonalne i może mieć tylko kluczetrueifalse.noulwymaga niepustychinstructionslub co najmniej jednego niepustego kryterium.choice: wybór jednej etykiety.criteriamapuje od 1 do 26 etykiet na wartości; puste ciągi znaków są odrzucane. Etykiety muszą być unikalne bez względu na wielkość liter i mieć do 256 znaków.score: ocena na skali.criteriato tablica od 2 do 10 niepustych poziomów, od najniższego. Indeksy poziomów zaczynają się od 0.
Nieznane pola są odrzucane. Treść żądania może mieć do 512 KiB, a stan wraz z najdłuższym pytaniem musi zmieścić się w kontekście modelu.
Odpowiedź
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: prawdopodobieństwo, że odpowiedź totrue, od 0 do 1.choice:choiceto najbardziej prawdopodobna etykieta,probabilitieszawiera wszystkie etykiety i sumuje się do 1, aconfidenceto wartość od 0 do 1.score:scoreto średnia indeksów poziomów ważona prawdopodobieństwem (od 0 do liczby poziomów minus 1). Kluczami wprobabilitiesilegendsą indeksy poziomów;legendprzypisuje każdemu indeksowi opis poziomu.confidenceto wartość od 0 do 1.modelto model, który odpowiedział.usage.output_tokenszawsze wynosi 0.
Wartości w przykładowej odpowiedzi są poglądowe.
Rozliczenia
Rozliczane są tylko tokeny wejściowe, po cenie wejściowej modelu. Model czyta stan raz na każde pytanie, więc
usage.input_tokens rośnie wraz z liczbą pytań. Przed wywołaniem blokada na saldzie obejmuje
(bajty stanu + bajty wszystkich pytań + 4 096) × liczba pytań, liczone jako tokeny wejściowe,
a żądanie jest rozliczane według usage.input_tokens, nigdy powyżej blokady. Nieudane żądania nie są
rozliczane; jeśli rozłączysz się po tym, jak model odpowiedział, jego tokeny wejściowe są naliczane. Okresy bezpłatne
działają tak samo jak w czacie.
Błędy
System One używa własnego formatu błędu: {"detail": "message"}, a dla 422 listy elementów
loc / msg / type, które wskazują pole.
json{
"detail": [
{"loc": ["body", "questions", "team", "criteria"], "msg": "choice accepts 1 to 26 criteria", "type": "too_long"}
]
} - 401: brak klucza lub nieprawidłowy klucz.
- 402: rozliczenia odrzuciły żądanie: saldo, limity wydatków albo nie udało się wycenić żądania. Powody są takie same jak w kodach 402, tu tylko jako tekst w
detail. - 404:
model not found, także dla modeli bezsupports_decisions. - 422: nieprawidłowa treść żądania, treść ponad 512 KiB, stan i pytania przekraczające kontekst albo model odrzucił żądanie.
- 429: osiągnięto limit klucza (
Retry-After: 5) albo każda wypróbowana trasa dostawcy trafiła na rate limit (Retry-Afterdostawcy, maksymalnie 60 sekund). - 502: model nie zdołał odpowiedzieć.
- 503: brak sprawnej trasy, brak trasy zgodnej z ustawieniami prywatności projektu albo nie udało się wczytać ustawień.
- 529: wszystkie trasy modelu są w pełni obciążone.
Retry-After: 5.
OCR
POST /v1/ocr ma format Mistral OCR. Wyślij plik bezpośrednio jako data URI w base64;
zdalne adresy URL są odrzucane. Obsługiwane są PDF, PNG, JPEG i WebP.
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: model OCR z publicznego katalogu (kind: "ocr").document:{"type": "document_url", "document_url": "data:..."}lub{"type": "image_url", "image_url": "data:..."}.pages(opcjonalne): indeksy stron do odczytania, liczone od 0. Nie każdy model OCR to obsługuje; hostowane modele OCR ifirecrawl/pdf-inspectorodpowiadają 400.include_image_base64(opcjonalne): zwraca osadzone obrazy w base64. Nie każdy model OCR zwraca obrazy; niektóre zawsze odpowiadają pustą listąimages.
Odpowiedź zawiera pages (każda z index, markdown i
images) oraz usage_info.pages_processed. Opłata jest naliczana za każdą przetworzoną stronę. Blokada obejmuje
cały dokument, a dokumenty przekraczające max_pages modelu są odrzucane.
firecrawl/pdf-inspector czyta tylko PDF-y wygenerowane cyfrowo. W przypadku obrazu API zwraca odpowiedź 422; PDF ze
zeskanowanymi stronami daje 422 z code: "pages_need_ocr" i listą tych stron w
pages_needing_ocr.
Błędy i limity
Każdy endpoint poza System One zwraca błędy w formacie OpenAI:
json{
"error": {
"message": "insufficient AI balance. Top up in the AI Billing tab.",
"type": "error",
"code": "empty_balance"
}
} message jest zawsze obecne. type oraz to, czy ustawiono code, zależą od
endpointu, więc najpierw sprawdzaj status HTTP. Chat, embeddings, rerank i narzędzia webowe umieszczają
kody 402 w code. Gdy trasa modelu odpowiada na chat, embeddings lub
rerank błędem HTTP, treść odpowiedzi zawiera również request_id. Nagłówek X-Request-ID
jest zawsze obecny.
- 400: nieprawidłowy JSON, brak
modellub model niewłaściwego rodzaju dla endpointu (np. model OCR w czacie). Treść żądania ponad 25 MiB, która dotrze do procesu API, dostaje komunikatrequest body exceeds 25 MiB. - 401: zobacz Uwierzytelnianie.
- 402: saldo odrzuciło żądanie; zobacz kody poniżej.
- 404:
model not foundlub endpoint, który nie istnieje. - 413: publiczny host odrzucił treść żądania większą niż 25 MiB, zanim zadziałało API.
- 429: osiągnięto limit klucza lub model jest przeciążony. Uwzględnij
Retry-After, jeśli zostanie wysłany. - 502: trasa modelu zawiodła. Spróbuj ponownie później.
- 503: brak sprawnej trasy dla modelu, brak trasy zgodnej z ustawieniami prywatności projektu (zakładka Settings) albo nie udało się wczytać ustawień.
Kody 402. Chat, embeddings, rerank i narzędzia webowe wysyłają je w code. OCR, audio i obrazy
wysyłają tylko komunikat, a System One wysyła go jako detail.
empty_balance: dostępne saldo AI nie pokrywa blokady dla tego żądania. Doładuj saldo w zakładce Billing albo włącz automatyczne doładowanie.daily_quota: dzisiejsze wydatki na tym kluczu plus jego otwarte blokady plus to żądanie przekroczyłyby dzienny limit wydatków klucza.month_quota: wydatki w tym miesiącu plus otwarte blokady plus to żądanie przekroczyłyby miesięczny limit wydatków ustawiony przez Ciebie w zakładce Billing.usage_limit: wydatki w tym miesiącu plus otwarte blokady plus to żądanie przekroczyłyby miesięczny limit Twojego poziomu zużycia (usage tier). Zakładka Billing pokazuje poziom i to, od kiedy obowiązuje następny.pricing_unavailableireserve_failed: nie udało się wycenić żądania ani zablokować kwoty. Spróbuj ponownie, a potem skontaktuj się z supportem, podając identyfikator żądania.
Domyślne limity na klucz:
- 600 żądań na minutę
- 4 000 000 tokenów na minutę (chat, embeddings, rerank i System One)
- 20 równoczesnych żądań
- 25 MiB treści żądania dla chat, embeddings, rerank, OCR, audio i obrazów. Narzędzia: 1 MiB. System One: 512 KiB.
Dla chat, embeddings i rerank odpowiedź 429 wysyła Retry-After: 5 przy limicie żądań i przy
przeciążeniu, 10 przy limicie tokenów i 2 przy limicie równoczesnych żądań. System One zawsze wysyła
Retry-After: 5. Tworzenie głosu wysyła Retry-After, gdy zadziałają jego własne limity (zbyt
wiele uploadów w toku lub ponad dziesięć prób utworzenia na godzinę). Inne odpowiedzi 429 dla OCR, audio, obrazów, narzędzi webowych
i głosów nie wysyłają tego nagłówka; odczekaj kilka sekund przed ponowną próbą. Skontaktuj się z supportem, jeśli potrzebujesz wyższych limitów.