Referência da API de IA

Todos os endpoints de api.nodion.ai/v1, com limites e erros.

URL base: https://api.nodion.ai/v1. A API segue o formato da OpenAI, pelo que os SDKs da OpenAI funcionam quando configurados com este URL base. Para as chaves, o saldo e os separadores do dashboard, consulte AI Inference. Os modelos, fornecedores e preços estão no catálogo de modelos.

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)

Autenticação

Envie uma chave de inferência (nodion_ai_…) como bearer token em cada pedido. As chaves da plataforma (nodion_…) não funcionam aqui. GET /v1/models é a única chamada que não precisa de chave.

httpAuthorization: Bearer nodion_ai_…

Uma chave recusada recebe a resposta 401 com uma destas mensagens:

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

Todas as respostas incluem o cabeçalho X-Request-ID. Indique-o quando contactar o suporte.

Os corpos dos pedidos JSON podem ter até 25 MiB (ferramentas 1 MiB, System One 512 KiB). O base64 acrescenta um terço, pelo que um ficheiro enviado inline no JSON, como uma imagem, um PDF ou um documento para OCR, pode ter cerca de 18 MiB. Os envios multipart para /v1/audio/transcriptions e /v1/audio/voices podem ter até 25 MiB, com ficheiros de transcrição até 20 MiB e ficheiros de amostra de voz até 10 MiB (11 MiB para o formulário inteiro).

Endpoints

Endpoint O que faz Faturado por
GET /v1/modelsLista os modelos com preço por tokenGratuito
POST /v1/chat/completionsChat, ferramentas, saída estruturadaTokens de entrada e de saída
POST /v1/responsesOpenAI Responses API, por exemplo para o CodexTokens de entrada e de saída
POST /v1/embeddingsEmbeddings vetoriaisTokens de entrada
POST /v1/rerankOrdena documentos em relação a uma consultaTokens de entrada
POST /v1/systemoneSystem One: decisões tipadas com probabilidadesTokens de entrada
POST /v1/ocrOCR de documentos e imagensPáginas
POST /v1/audio/transcriptionsVoz para textoSegundos de áudio
GET /v1/audio/transcriptions/realtime (WebSocket)Voz para texto em tempo realSegundos de áudio
POST /v1/audio/speechTexto para vozCaracteres
GET, POST /v1/audio/voicesLista e cria vozes clonadasGratuito
GET, DELETE /v1/audio/voices/{id}Lê ou elimina uma voz clonadaGratuito
POST /v1/images/generationsGeração de imagensImagens
POST /v1/tools/web_search, web_news, web_fetch, web_images, web_videos, web_places, web_maps, web_shopping, web_lensFerramentas webChamadas, mais cada página obtida por um web_search

O áudio, as imagens e as ferramentas estão descritos com exemplos em AI Inference. O resto está abaixo.

Antes de cada chamada, é reservado no saldo o valor máximo possível para o custo do pedido. O valor final é calculado com base na utilização comunicada, nunca acima da reserva, e o restante é libertado. Se uma resposta bem-sucedida não reportar utilização, é cobrada a reserva completa. Uma sessão de transcrição em tempo real reserva o max_audio_seconds do modelo (1 800 segundos se o modelo não definir nenhum), pelo que o saldo tem de cobrir uma sessão completa à partida.

Modelos

GET /v1/models devolve {"object": "list", "data": [...]} e lista modelos de chat, embeddings e rerank. Os modelos de OCR, voz, imagem e ferramentas não estão incluídos; o catálogo público em https://api.nodion.com/v2/public/ai/models lista todos os tipos. Campos úteis por modelo:

  • id: o valor de model nos pedidos.
  • kind: chat, embeddings ou rerank.
  • context_length e max_output_length em tokens.
  • pricing: USD por token como strings decimais. pricing_eur tem os preços em EUR.
  • supported_sampling_parameters e supported_features (por exemplo tools, json_mode, structured_outputs, reasoning).
  • reasoning_efforts: os valores de reasoning_effort que este modelo aceita (por exemplo none, low, high). Vazio quando os níveis não são configuráveis.
  • is_ready: false significa que, neste momento, nenhuma rota está operacional. O modelo continua listado.
  • lifecycle: ga ou preview. serving: hosted (os pesos do modelo correm na Nodion) ou routed (encaminhado para um fornecedor).
  • supports_decisions: o modelo responde ao System One.
  • coding_plan: o Codion pode oferecer este modelo de chat. Sempre true ou false. Não corresponde ao plano de programação com IA usado na faturação.
  • free_until: definido enquanto estiver ativo um período gratuito num modelo servido apenas pela Nodion. Os preços por token mostram então 0.

Chat completions

POST /v1/chat/completions aceita o corpo da OpenAI Chat Completions: model, messages e os campos opcionais que o modelo indica em supported_sampling_parameters e supported_features, como tools ou response_format. Envie reasoning_effort apenas quando reasoning_efforts não estiver vazio, e apenas com um valor dessa lista.

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

O que o gateway faz ao pedido e à resposta:

  • Sem max_tokens (ou max_completion_tokens), o gateway define max_tokens com o max_output_length do modelo. Valores superiores são reduzidos a esse limite.
  • Com "stream": true, a resposta chega como server-sent events (linhas data: {...}, depois data: [DONE]). O gateway define stream_options.include_usage, pelo que o último chunk inclui normalmente a utilização. Se a ligação upstream cair a meio do stream, um último chunk traz um objeto error e finish_reason: "error", seguido de data: [DONE].
  • O campo model na resposta é o id enviado no pedido. O texto de raciocínio, quando um modelo o devolve, está em reasoning_content.

Os ficheiros PDF podem ser enviados inline como bloco de conteúdo file com um data URI em base64. Antes da chamada, o gateway converte as primeiras 20 páginas em imagens, pelo que isto só ajuda em modelos com entrada de imagem. As referências file_id são recusadas.

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

Faturação: tokens de entrada e de saída ao preço do modelo, entrada em cache ao preço de cache quando a rota o reporta. A reserva conta cada byte do pedido como um token de entrada, mais max_tokens. Em pedidos com imagens ou PDF, a parte de entrada sobe para o comprimento de contexto do modelo, ou para pelo menos 128 000 tokens quando o pedido é maior do que o contexto. Durante o período gratuito de um modelo (free_until), as chat completions em rotas alojadas são gratuitas.

Responses API

POST /v1/responses aceita o corpo da OpenAI Responses API: model, input (texto ou uma lista de itens) e os campos opcionais instructions, tools, tool_choice, parallel_tool_calls, text.format, reasoning.effort, max_output_tokens, max_tool_calls, temperature, top_p, top_logprobs, include e stream. O gateway traduz o pedido para uma chat completion, pelo que tudo o que consta da secção de chat completions também se aplica aqui: o limite de saída, os reasoning_efforts permitidos, os PDF e a faturação.

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

Com "stream": true, a resposta é o stream de eventos da Responses API, como response.created, response.output_text.delta e response.function_call_arguments.delta, terminando com response.completed e o respetivo usage. Se o stream for interrompido, o último evento é response.failed. O texto de raciocínio chega num item reasoning como reasoning_text. Devolva esse item nos pedidos seguintes: o raciocínio desde a última mensagem do utilizador volta ao modelo, o raciocínio mais antigo só com reasoning.context: "all_turns".

O gateway executa ele próprio o web_search, através da pesquisa web da Nodion. Quando o modelo pesquisa, o gateway obtém os resultados, entrega-os ao modelo e volta a chamá-lo. A resposta inclui um item web_search_call com a consulta e os URL das fontes, transmitido em stream com os eventos response.web_search_call.in_progress, searching e completed. Faturação: cada pesquisa como uma chamada a /v1/tools/web_search, cada ronda do modelo como uma chat completion, e usage é a soma de todas as rondas. Uma Response conta uma vez para o limite de pedidos da chave. No máximo max_tool_calls pesquisas por Response (10 por omissão, 20 no máximo); max_output_tokens abrange todas as rondas em conjunto. filters.allowed_domains, user_location (cidade, região, país) e search_context_size (5, 10 ou 20 resultados) são aplicados. A pesquisa devolve apenas resultados do índice de pesquisa (título, URL, excerto) e não abre páginas, mesmo com external_web_access: true.

Logprobs: com top_logprobs (até 20) ou include: ["message.output_text.logprobs"], aparecem em output_text quando o modelo os devolve.

Com esta configuração, o Codex CLI funciona com a Nodion, incluindo a pesquisa web:

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"

Diferenças em relação à OpenAI:

  • A Nodion não guarda respostas. store é ignorado e a resposta indica store: false. Não existe previous_response_id, conversation, item_reference nem GET /v1/responses/{id}. Envie a conversa completa em input, como faz o Codex.
  • Ferramentas: function, custom, namespace e web_search. Outras ferramentas alojadas, como file_search ou code_interpreter, são recusadas com 400.
  • Os resultados de pesquisa não são guardados. Um web_search_call na conversa chega ao modelo como a chamada acompanhada de uma nota, sem os resultados antigos. annotations (citações) fica vazio; as fontes estão no web_search_call.
  • As imagens e os ficheiros nos resultados das ferramentas não chegam ao modelo; uma nota no texto substitui-os.
  • Não suportado (400): background, prompt, truncation: "auto", file_id e file_url. Envie as imagens como image_url (um URL ou data URI) e os PDF como input_file com file_data.

Embeddings

POST /v1/embeddings aceita o corpo da OpenAI (model, input como string ou array) e devolve a resposta de embeddings da OpenAI. Sem streaming. Faturado com base em usage.prompt_tokens. Use um modelo com 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 pontua documents em relação a uma query. O campo opcional top_n limita os resultados. A resposta tem results com index (posição em documents) e relevance_score, mais usage.prompt_tokens, que é a base da faturação. Use um modelo com 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 responde a perguntas tipadas sobre um estado. Em vez de escrever texto, o modelo pontua cada resposta possível, pelo que recebe probabilidades e não prosa. Use-o para encaminhamento, triagem, moderação ou como ponto de controlo antes de um agente executar uma ferramenta. Uma chamada responde a até 16 perguntas sobre o mesmo estado.

Os modelos com supports_decisions: true em /v1/models servem o System One. O System One corre em rotas alojadas pela Nodion e em fornecedores que oferecem eles próprios o System One. Se uma rota falhar antes de executar o pedido (rate limit, falha de serviço), o mesmo pedido passa para a rota seguinte. O separador Decisions no Playground tem exemplos prontos a usar.

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

Pedido

  • model (obrigatório): um modelo com supports_decisions.
  • state (obrigatório): aquilo a que as perguntas se referem. Uma string, um objeto, um array ou null.
  • questions (obrigatório): um objeto com 1 a 16 entradas. A chave é o nome que dá à pergunta (até 128 caracteres) e volta como chave em answers.

Cada pergunta tem um type, instructions opcionais e criteria que dependem do tipo. Os valores de instruções e critérios podem ser uma string, um objeto ou um array; null é permitido em todo o lado, exceto nos níveis de score.

  • noul: uma pergunta de sim/não. criteria é opcional e só pode ter as chaves true e false. Um noul precisa de instructions não vazias ou de pelo menos um critério não vazio.
  • choice: escolher uma etiqueta. criteria faz corresponder 1 a 26 etiquetas a um valor; strings em branco são recusadas. As etiquetas têm de ser únicas, sem distinção entre maiúsculas e minúsculas, e ter até 256 caracteres.
  • score: classificar numa escala. criteria é um array de 2 a 10 níveis não vazios, do mais baixo para o mais alto. Os índices dos níveis começam em 0.

Os campos desconhecidos são recusados. O corpo pode ter até 512 KiB, e o estado mais a maior pergunta têm de caber no contexto do modelo.

Resposta

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: a probabilidade de a resposta ser true, de 0 a 1.
  • choice: choice é a etiqueta mais provável, probabilities tem todas as etiquetas e soma 1, e confidence é um valor de 0 a 1.
  • score: score é a média dos índices dos níveis ponderada pelas probabilidades (de 0 até ao número de níveis menos 1). probabilities e legend têm como chave o índice do nível; legend faz corresponder cada índice a uma descrição de nível. confidence é um valor de 0 a 1.
  • model é o modelo que respondeu. usage.output_tokens é sempre 0.

Os valores da resposta de exemplo são ilustrativos.

Faturação

Apenas os tokens de entrada são faturados, ao preço de entrada do modelo. O modelo lê o estado uma vez por pergunta, pelo que usage.input_tokens cresce com o número de perguntas. Antes da chamada, o saldo reserva (bytes do estado + bytes de todas as perguntas + 4 096) × o número de perguntas como tokens de entrada, e o pedido é liquidado com base em usage.input_tokens, nunca acima da reserva. Os pedidos que falham não são faturados; se fechar a ligação depois de o modelo ter respondido, os tokens de entrada são faturados. Os períodos gratuitos aplicam-se como no chat.

Erros

O System One usa um formato de erro próprio: {"detail": "message"} e, para 422, uma lista de itens loc / msg / type que indicam o campo.

json{
  "detail": [
    {"loc": ["body", "questions", "team", "criteria"], "msg": "choice accepts 1 to 26 criteria", "type": "too_long"}
  ]
}
  • 401: chave em falta ou inválida.
  • 402: a faturação recusou o pedido: saldo, limites de gastos, ou não foi possível calcular o preço do pedido. Os motivos são os dos códigos 402, aqui apenas como texto em detail.
  • 404: model not found, também para modelos sem supports_decisions.
  • 422: corpo inválido, corpo acima de 512 KiB, estado e perguntas acima do contexto, ou o modelo recusou o pedido.
  • 429: foi atingido um limite da chave (Retry-After: 5), ou todas as rotas de fornecedor tentadas atingiram o rate limit (o Retry-After do fornecedor, no máximo 60 segundos).
  • 502: o modelo não conseguiu responder.
  • 503: nenhuma rota operacional, nenhuma que corresponda às definições de privacidade do projeto, ou não foi possível carregar as definições.
  • 529: todas as rotas do modelo estão no limite da capacidade. Retry-After: 5.

OCR

POST /v1/ocr segue o formato do Mistral OCR. Envie o ficheiro inline como data URI em base64; os URL remotos são recusados. Funcionam PDF, PNG, JPEG e 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: um modelo de OCR do catálogo público (kind: "ocr").
  • document: {"type": "document_url", "document_url": "data:..."} ou {"type": "image_url", "image_url": "data:..."}.
  • pages (opcional): índices das páginas a ler, a começar em 0. Nem todos os modelos de OCR o suportam; os modelos de OCR alojados e firecrawl/pdf-inspector respondem 400.
  • include_image_base64 (opcional): devolve as imagens incorporadas em base64. Nem todos os modelos de OCR devolvem imagens; alguns respondem sempre com uma lista images vazia.

A resposta tem pages (cada uma com index, markdown e images) e usage_info.pages_processed. Faturado por página processada. A reserva cobre o documento inteiro, e os documentos acima do max_pages do modelo são recusados. firecrawl/pdf-inspector só lê PDF gerados digitalmente. Uma imagem recebe 422; um PDF com páginas digitalizadas recebe 422 com code: "pages_need_ocr" e as páginas afetadas em pages_needing_ocr.

Erros e limites

Todos os endpoints, exceto o System One, devolvem os erros no envelope da OpenAI:

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

message está sempre presente. O valor de type e a presença de code variam consoante o endpoint. Por isso, verifique primeiro o código de estado HTTP. Chat, embeddings, rerank e as ferramentas web colocam os códigos 402 em code. Quando a rota do modelo responde a chat, embeddings ou rerank com um erro HTTP, o corpo inclui também request_id. O cabeçalho X-Request-ID está sempre presente.

  • 400: JSON inválido, model em falta, ou um modelo do tipo errado para o endpoint (por exemplo, um modelo de OCR no chat). Um corpo acima de 25 MiB que chegue ao processo da API recebe request body exceeds 25 MiB.
  • 401: consulte Autenticação.
  • 402: o saldo recusou o pedido; consulte os códigos abaixo.
  • 404: model not found, ou um endpoint que não existe.
  • 413: o host público recusou um corpo acima de 25 MiB antes de a API ser executada.
  • 429: foi atingido um limite da chave, ou o modelo está sobrecarregado. Respeite o Retry-After quando for enviado.
  • 502: a rota do modelo falhou. Tente novamente mais tarde.
  • 503: nenhuma rota operacional para o modelo, nenhuma que corresponda às definições de privacidade do projeto (separador Settings), ou não foi possível carregar as definições.

Códigos 402: chat, embeddings, rerank e as ferramentas web enviam-nos em code. OCR, áudio e imagens enviam apenas a mensagem, e o System One envia-a como detail.

  • empty_balance: o saldo de IA disponível não cobre a reserva deste pedido. Carregue o saldo no separador Billing ou ative o carregamento automático.
  • daily_quota: os gastos de hoje nesta chave, mais as suas reservas em aberto, mais este pedido ultrapassariam o limite diário de gastos da chave.
  • month_quota: os gastos deste mês, mais as reservas em aberto, mais este pedido ultrapassariam o limite mensal de gastos definido no separador Billing.
  • usage_limit: os gastos deste mês, mais as reservas em aberto, mais este pedido ultrapassariam o teto mensal do seu nível de utilização (usage tier). O separador Billing mostra o nível e quando se aplica o seguinte.
  • pricing_unavailable e reserve_failed: não foi possível calcular o preço do pedido ou fazer a reserva. Tente novamente e, depois, contacte o suporte com o id do pedido.

Limites por chave definidos por omissão:

  • 600 pedidos por minuto
  • 4 000 000 tokens por minuto (chat, embeddings, rerank e System One)
  • 20 pedidos em simultâneo
  • 25 MiB de corpo de pedido em chat, embeddings, rerank, OCR, áudio e imagens. Ferramentas: 1 MiB. System One: 512 KiB.

Em chat, embeddings e rerank, um 429 envia Retry-After: 5 para a taxa de pedidos e para sobrecarga, 10 para a taxa de tokens e 2 para a concorrência. O System One envia sempre Retry-After: 5. A criação de uma voz envia Retry-After quando atinge os seus próprios limites (demasiados uploads em curso, ou mais de dez tentativas de criação por hora). As restantes respostas 429 em OCR, áudio, imagens, ferramentas web e vozes não o enviam; aguarde alguns segundos antes de tentar novamente. Contacte o suporte se precisar de limites mais altos.

Dê uma cloud ao seu agente.

Ganhe até 15 € de crédito ao registar-se.

Continuar com o GitHub

ou com e-mail

Fique a par das novidades.

Novidades do produto, sem spam. Pode cancelar a subscrição a qualquer momento.