niuronniuron
docs

Build with niuron

Connect your application, configure routing and add tools. Find API examples and organization controls in /app, organized around your workflow.

where: your code, via API key

Chat completions API

POST /v1/chat/completions is the chat endpoint: it classifies the request, picks a model, executes it against the winning provider, and returns an OpenAI-shaped response. Point your existing OpenAI SDK at https://api.niuron.ai/v1 with a router API key (create one in /app/api-keys) and nothing else about your client code changes. For structured decisions with TypeSafe Jev, use the dedicated section below.

curl
curl https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer ar_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Explain routing in one sentence."}]
  }'
  • model: "auto" lets the router score every eligible model on cost, latency, quality, and reliability and pick the winner. Pin a specific canonical name instead (e.g. gpt-4o, claude-sonnet-5) to skip that decision — the response shape is identical either way.
  • response.model reports the canonical name actually used, not the provider's raw model string — safe to log or re-request explicitly.
  • stream: true works the same way it does against OpenAI — server-sent events, one chunk at a time.
POST /v1/responses

Responses API

Use POST /v1/responses with the same Bearer API key and model names as Chat Completions. This stateless compatibility endpoint translates into the shared chat pipeline, retaining routing profiles, tenant policies, retries, billing and telemetry. It does not proxy the provider’s native Responses endpoint.

curl
curl https://api.niuron.ai/v1/responses \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "input": "Explain consistent hashing in two sentences.",
  "instructions": "Be concise.",
  "max_output_tokens": 512,
  "store": false
}'

Read text from output items of type message, then their output_text content parts. Output can also contain function calls. Inspect status and error before using it. usage includes input/output/total tokens and cached/reasoning details when reported by the provider.

  • input accepts a string or message/item array. Message content accepts text and input_image parts with image_url; vision requires a compatible model. instructions and developer messages become system messages.
  • max_output_tokens, temperature, top_p and routing use the shared pipeline. Model-specific restrictions still apply.
  • Send the full history every turn. Omit store or set it to false. store: true and any non-null previous_response_id return HTTP 400. Responses cannot be retrieved later by ID.

Reasoning and structured output

Set reasoning.effort to high to control reasoning effort. Accepted values are none, minimal, low, medium, high, xhigh and max; the supported subset depends on the model. Only effort is supported: summaries and encrypted reasoning history are rejected.

text.format supports text, json_object and json_schema. Schema options are flat: name, description, schema and strict. A schema requires a name and an object schema; the provider validates and enforces its schema dialect. The result remains JSON text inside an output_text part.

JSON · POST /v1/responses
{
  "model": "niuron/auto",
  "input": "Return the capital of Brazil as JSON.",
  "text": {
    "format": {
      "type": "json_schema",
      "name": "capital",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "capital": {
            "type": "string"
          }
        },
        "required": [
          "capital"
        ],
        "additionalProperties": false
      }
    }
  }
}

Reasoning effort and structured output currently require an OpenAI-compatible adapter. Anthropic and Gemini adapters are excluded for these requests because their mappings do not carry these controls. Non-none effort also requires a model marked as supporting reasoning. Native Responses-only features remain unsupported by the upstream Chat Completions transport.

Function calling and continuation

Declare functions directly on the tool object, without a nested function object. tool_choice accepts auto, none, required or a function object with type: function and name: lookup_order. parallel_tool_calls: false excludes adapters unable to honor it.

JSON · POST /v1/responses
{
  "model": "niuron/auto",
  "input": "Look up order 42.",
  "tools": [
    {
      "type": "function",
      "name": "lookup_order",
      "description": "Get an order by ID",
      "parameters": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      },
      "strict": true
    }
  ]
}

Execute returned function calls in your client. For the next request, keep the original input, append all returned output items, then a function_call_output for each call. Copy the returned call_id, not the item ID; the example ID below is illustrative. Tool output must be a string, so serialize structured results as JSON text. Resend the relevant tools and instructions.

JSON · next request with illustrative tool result
{
  "model": "niuron/auto",
  "input": [
    {
      "role": "user",
      "content": "Look up order 42."
    },
    {
      "type": "function_call",
      "call_id": "call_123",
      "name": "lookup_order",
      "arguments": "{\"id\":42}"
    },
    {
      "type": "function_call_output",
      "call_id": "call_123",
      "output": "{\"status\":\"shipped\"}"
    }
  ],
  "tools": [
    {
      "type": "function",
      "name": "lookup_order",
      "description": "Get an order by ID",
      "parameters": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      },
      "strict": true
    }
  ]
}

Native web_search/web_search_preview retains existing provider restrictions. Search citations and hosted-tool output items are not reconstructed; text annotations are empty. Niuron-managed tools have their own execution flow: see Server-executed tools.

Streaming and terminal events

Set stream: true and consume SSE event/data pairs. Events have a type and increasing sequence_number starting at zero. The stream starts with response.created and response.in_progress, followed by text or function-argument deltas and done events. Item indices match the final output array. Wait for completed arguments before executing a function.

  • response.completed: successful completion, including a turn that returns function calls.
  • response.incomplete: token limit or content filtering. Inspect incomplete_details.reason for max_output_tokens or content_filter.
  • response.failed: provider failure. Inspect error; partial output must not be treated as a completed function call.

Limitations and caching

Unsupported request fields and reasoning/text options return HTTP 400 with invalid_request_error. Background execution, automatic truncation and non-empty include are rejected. Files/audio, reasoning summaries or encrypted items, item references, computer use and native file search are unsupported. Retrieval, deletion, cancellation, compaction and WebSocket endpoints are not implemented.

store: false controls Responses conversation persistence; inference caching is separate. Send Cache-Control: no-store or disable caching in organization settings to skip cache reads/writes and shadow routing. Exact cache keys include effort and response format; requests with either control bypass semantic caching.

where: /app/chat

Chat playground

A chat UI in the dashboard that runs through the exact same classify-route-execute pipeline the API uses — useful for trying the router, comparing models, or debugging a prompt without writing a curl command. Authenticated by your dashboard session, not an API key.

  • Pick a model (or leave it on auto) when starting a new conversation — it's fixed for that conversation once the first message goes out.
  • Every reply shows which model and provider actually answered, and can be copied, regenerated (re-runs only the latest reply against fresh context), or deleted.
  • Conversations persist per user, not shared across your team.
  • It's real usage, not a sandbox — every message is a real provider call and shows up in request history and billing the same as an API call.
  • Responses arrive complete, not streamed token-by-token, in this first version.
/app/settings · Routing

Organization routing policy

Owners and admins configure routing in Settings → Routing. Settings belong to the active organization, not a user or individual key, and apply to all its chat requests.

  • Allowed and excluded lists accept canonical model IDs or provider/model patterns. * matches any substring, including slashes. Example: anthropic/*. Patterns are case-sensitive. The UI accepts commas or newlines; the API uses arrays. Limit: 100 patterns per list, 256 characters per pattern.
  • Exclusions win over allowed patterns. Empty lists impose no restriction. Explicit model names, presets, free-chain slots and fallback models must all satisfy the lists. No matching model returns 404 invalid_request_error; the router never silently leaves the lists.
  • Requests may replace individual defaults through routing.cost_tier, routing.allowed_models and routing.excluded_models. Omitted fields inherit; an empty array clears that list. Enable Enforce organization rules so requests cannot change the cost preference or model lists defined in Settings. Invalid options return 400 even when this setting is enabled.
  • Cost tier remains a preference: low, medium, high and xhigh consider the cheapest 20%, 40%, 60% and 80% of the enabled catalog; max is unrestricted. If the band has no compatible candidate, the router relaxes the band, but never the model lists.
  • Requests with a restrictive model policy or a routing object bypass exact/semantic response caches and shadow comparisons. This prevents an old cached answer from bypassing a new policy.
  • Supported by chat completions, Responses and Anthropic Messages, including streaming, and by the chat playground. TypeSafe Jev's separate decision API is not part of chat routing. Updates are immediate on the gateway that saved them; other replicas refresh within 15 seconds.
JSON · /v1/chat/completions
{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "Explain routing in one sentence."
    }
  ],
  "routing": {
    "cost_tier": "low",
    "allowed_models": [
      "anthropic/*",
      "openai/*"
    ],
    "excluded_models": [
      "*preview*"
    ]
  }
}
/app/settings/profiles

Application routing profiles

Create a profile in Settings → Routing profiles, then send its identifier as the model. Profiles belong to the organization and define priorities, model lists and capability requirements. Niuron still selects the model for each prompt.

JSON · /v1/chat/completions
{
  "model": "niuron/profile/support",
  "messages": [
    {
      "role": "user",
      "content": "Explain this code."
    }
  ]
}
  • Use niuron/profile/support for the active version or niuron/profile/support@v2 to pin version 2. Responses report the resolved version in X-Niuron-Profile-Version. Saving or restoring activates a new version; existing pinned versions are unchanged. Supported by chat completions, Responses, Anthropic Messages and chat, including streaming.
  • Organization model restrictions always apply. When organization rules are enforced, its cost preference takes precedence too. Profiles cannot be combined with the request's routing object. Model capability requirements do not themselves set output format. Response caches and shadow comparisons are bypassed.
  • Preview is a free deterministic simulation and may differ from production classification. A real chat test consumes credits. The profile page shows its latest 50 versions and 30-day inference cost, requests, errors and latency. Owners/admins edit and view metrics; members may inspect and test.
where: your code, via API key

Tool calling

Define functions with tools and control their selection with tool_choice. Niuron normalizes function calling across compatible model adapters, so your application can execute a function and return its result through the same API contract when the selected model changes. With model: "auto", the router selects a compatible model per request. This section covers functions your application executes; Niuron-executed web tools and native provider tools have separate capabilities and restrictions.

curl
curl https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer ar_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Weather in Boston?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}
      }
    }],
    "tool_choice": "auto"
  }'
  • tool_choice — "auto", "none", "required", or pinning one specific tool by name — is honored identically whether the winning model is OpenAI, Anthropic, or Gemini. A pinned tool_choice used to be silently ignored on some providers; every provider now forces it the same way.
  • Your tool's JSON Schema (parameters) travels through to every provider close to byte-for-byte — including additionalProperties, $ref, and multi-type unions, which an older, more restrictive Gemini API field used to reject outright. niuron sends it through Gemini's own broader JSON-Schema-accepting field instead of rewriting your schema to fit a narrower one — not a claim that every JSON Schema keyword in existence is guaranteed to work on every provider.
  • /v1/responses accepts client-defined function tools and Niuron server tools in separate requests. Native web_search is forwarded only to compatible providers; unsupported hosted types such as file_search return an explicit error instead of being silently discarded. See Server-executed web tools for Niuron's managed execution loop.
  • Works the same across every wire protocol this gateway speaks — /v1/chat/completions' tools/tool_choice, /v1/messages' Anthropic-shaped equivalent, and /v1/responses' — not just the OpenAI-shaped endpoint shown here.
tools · web · datetime · subagent

Server-executed tools

Let Niuron execute tools and return the final model answer: search the web, read public URLs, check current date/time, or delegate an isolated reasoning task. Available on Chat Completions, Responses and Anthropic Messages, with organization permissions, bounded execution and usage history.

These are different from ordinary function calling: with type: function, your application executes the function and sends back its result. With the four Niuron tool types below, Niuron executes the tool. Do not execute the internal functions yourself or implement a second tool loop for them.

1. Enable tools for your organization

  1. Select the organization that owns your API key, then open Settings → Server tools. Tools are disabled by default, including for existing organizations without tool settings.
  2. An organization owner or admin enables each tool independently: public URL reads, web search, current date/time and isolated subagents. Members may use permitted tools but cannot change organization permissions. Enabling subagent does not enable tools for its child.
  3. Set allowed domains, the maximum number of tool calls per request (1–8, default 4), and the search fee ceiling ($0–$0.20 per request, default $0.04). These are organization settings, not request-body overrides.
  4. Use your normal Niuron API key as the bearer token. It must belong to the enabled organization and have access to a compatible model and sufficient credits for billable work.

If Web search is unavailable, ask the platform operator to configure the search integration. Application clients do not need a separate Exa key. Public URL reading does not require a search-provider key.

Choose the tools you need
Tool typeWhat Niuron does
niuron:web_searchSearches through the platform search integration and returns up to five source URLs with bounded text excerpts to the model. The model generates the query; it is not a request-body query parameter. May incur search fees.
niuron:web_fetchReads a public HTTP/HTTPS URL selected by the model using GET or HEAD. Useful when you already have a URL. No extra tool fee; model token costs still apply. It is not a full browser and does not execute page JavaScript, log in or access authenticated pages.
niuron:datetimeReturns the current server time in UTC or an IANA timezone. No network and no extra tool fee.
niuron:subagentRuns an isolated, bounded model call for a self-contained task. No child tools or recursion. Normal model-token billing, no extra tool fee.

2. Make an API request

Set NIURON_API_KEY in your shell and run the example. Supply only the hosted tool types in tools: do not add function schemas, credentials or custom query/URL parameters to those objects. Put the research task or public URL in the user message. The examples use curl -i to display the tool receipt headers.

curl · POST /v1/chat/completions
curl -i https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "Search for the latest PostgreSQL release notes, read the official source and cite its URL."
    }
  ],
  "tools": [
    {
      "type": "niuron:web_search"
    },
    {
      "type": "niuron:web_fetch"
    }
  ]
}'

Niuron routes to a tool-capable model. The model may request one or more tools; Niuron executes allowed calls and sends their results back to the model until it answers or a limit is reached. Simply enabling a tool does not guarantee it will be called. The response uses the endpoint's normal answer format, not an internal function-call payload your application must execute.

Example: Responses API
curl · POST /v1/responses
curl -i https://api.niuron.ai/v1/responses \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "input": "Search for the latest PostgreSQL release notes, read the official source and cite its URL.",
  "tools": [
    {
      "type": "niuron:web_search"
    },
    {
      "type": "niuron:web_fetch"
    }
  ]
}'
Example: Anthropic Messages API
curl · POST /v1/messages
curl -i https://api.niuron.ai/v1/messages \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "Search for the latest PostgreSQL release notes, read the official source and cite its URL."
    }
  ],
  "tools": [
    {
      "type": "niuron:web_search"
    },
    {
      "type": "niuron:web_fetch"
    }
  ],
  "max_tokens": 1024
}'
Example: read a known URL without search
curl · POST /v1/chat/completions
curl -i https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "Read https://www.postgresql.org/docs/ and summarize what this documentation covers. Cite the URL."
    }
  ],
  "tools": [
    {
      "type": "niuron:web_fetch"
    }
  ]
}'

Use niuron/auto for automatic selection or a specific enabled model ID returned by the model catalog. Explicitly selecting a model does not bypass its tool capability requirements or organization restrictions. Request bodies and final response formats remain specific to each endpoint.

Date/time: niuron:datetime

Reads the current server clock without accessing an external service. The model can supply an IANA timezone such as America/Sao_Paulo; the default is UTC. The tool returns datetime, utc, unix_time, timezone, utc_offset_seconds and weekday for the same instant. It does not convert arbitrary historical timestamps or accept the server-local Local zone. Invalid/unknown zones return a tool error. No extra tool fee, but parent model rounds still consume tokens.

Example: current time in a specific timezone
curl -i https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "What is the current date and time in America/Sao_Paulo? Use the datetime tool."
    }
  ],
  "tools": [
    {
      "type": "niuron:datetime"
    }
  ],
  "tool_choice": "required"
}'

Delegation: niuron:subagent

Delegates one self-contained reasoning, review or summarization task to a separate model call. The model supplies a task of up to 8000 bytes; include needed context there. Niuron does not automatically forward conversation history or credentials, but anything included in task is sent to the child model. It inherits the parent model field or pinned profile and all organization model restrictions. With an automatic routing preset, the router may select a different eligible model for the subtask. Clients and models cannot specify a separate subagent model in tool arguments.

The child has no tools, network access, recursive delegation or ability to perform external actions. Maximum 2 child calls per root request, also counted against the shared organization tool-call limit. Each child has at most 1024 output tokens and 40 seconds within the parent's two-minute loop. A token-limited result is marked truncated. Treat its answer as advisory output and synthesize or verify it; it is not an independently verified fact source.

Example: delegate an independent review
curl -i https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/auto",
  "messages": [
    {
      "role": "user",
      "content": "Delegate an independent comparison of TTL-based and event-based cache invalidation, then synthesize the trade-offs."
    }
  ],
  "tools": [
    {
      "type": "niuron:subagent"
    }
  ],
  "tool_choice": "required"
}'

Organization Settings has a separate maximum estimated subagent model cost: default $0.05, range $0–$0.20 per root request. Routing/fallback estimates must fit the remaining ceiling before a child is dispatched, and billing outages fail closed. The child's maximum estimate occupies its budget slot for the rest of the request, even if actual cost is lower; zero disables dispatch. This bounds admitted estimates, not a guarantee against erroneous provider usage reports. Actual child tokens are billed through normal inference exactly once; the tool wrapper never debits them again. Model BYOK is preserved. Parent rounds and web search fees are outside this ceiling.

X-Niuron-Subagent-Cost-USD reports the child's model cost separately from search fees. It is already represented by child inference usage, not an additional fee; with BYOK the model charge follows your provider key instead of a Niuron token debit. The tool audit displays that model cost for visibility, while the child is charged under its distinct request_id. Do not add the audit row to the child's billed usage a second time. Final token usage includes successful parent and child rounds. Tool audit records do not store the delegated task or answer.

3. Reuse tools through a profile or chat

In Settings → Routing profiles, create a research profile, enable its web tools and optionally narrow its allowed domains. The following fields are part of the profile configuration, not top-level fields of a chat completion request.

Profile configuration fields
{
  "server_tools": [
    "niuron:web_search",
    "niuron:web_fetch"
  ],
  "tool_allowed_domains": [
    "postgresql.org"
  ]
}

After creating a profile with slug research and version 1, call its reference instead of repeating the tool list. The reference below is an example: create the profile in your organization before using it.

curl · POST /v1/chat/completions
curl -i https://api.niuron.ai/v1/chat/completions \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "niuron/profile/research@v1",
  "messages": [
    {
      "role": "user",
      "content": "Search for the latest PostgreSQL release notes, read the official source and cite its URL."
    }
  ]
}'
  • Use niuron/profile/research to follow the active version or niuron/profile/research@v1 to pin an immutable configuration. Saving tool changes creates a new profile version. Deterministic profile previews do not execute tools.
  • Organization permissions always apply, including to pinned versions. Profile domains intersect with organization domains: a profile cannot grant access to a domain the organization forbids. Revoking a tool at organization level blocks new requests that depend on it.
  • A profile's server_tools list enables tools automatically. It is a default list, not a separate tool denylist: explicit request tools may add other organization-permitted Niuron tools. Do not combine profile defaults with client-executed functions or native provider tools.

In the chat, open the Tools menu and choose Public HTTP, Web search, Current date & time or Isolated subagent. Disabled options mean the tool is not available under the current organization settings or search integration. Selecting a profile with server tools enables its defaults even when manual options are off. Model continuations and child model calls consume credits here too.

Domain rules, limits and streaming

  • Allowed domains are DNS names such as postgresql.org, without schemes, paths, ports, IP addresses or wildcards. Commas or newlines separate entries in Settings; subdomains are included. An empty list allows all public domains, not private networks. Up to 50 domains are supported.
  • For example, organization postgresql.org plus profile www.postgresql.org permits that host and its subdomains, not an unrelated site. Disjoint organization/profile lists are rejected before model execution. Search results are filtered by the effective domain policy.
  • URL reads allow only HTTP/HTTPS on standard ports, GET/HEAD, and text/JSON/XML content, up to 16 KiB. Oversized text is truncated. Credentials in URLs, private/reserved networks and redirects are blocked; provide the final allowed URL rather than relying on a redirect. POST and other state-changing methods are not supported.
  • Each URL read is bounded to 8 seconds, each search to 12 seconds, and the tool continuation loop to 2 minutes. Existing model/provider deadlines still apply. Invalid or blocked calls also consume the per-request call count. Once exhausted, Niuron asks the model to finish from available results; further tool calls can cause an error.
  • With stream: true, this version buffers all server-tool rounds and sends only the final answer as SSE. It does not stream tokens during lookups or emit intermediate tool-call events for your client to execute. Set client and reverse-proxy timeouts to accommodate the lookup phase.
  • Do not mix Niuron tools with type: function or native provider tools such as web_search in one request: mixed ownership is rejected. Native provider web search is not an alias for Niuron web search. Unsupported hosted types are rejected explicitly, not silently ignored.
  • Server-tool requests do not read or write the response cache, including intermediate model rounds. Repeating a request can perform new searches, model calls and charges.

Understand the charges before enabling

  • Each model round consumes tokens, including the initial tool decision and later continuations. A research request can therefore cost more than one ordinary completion. Model usage already incurred remains billable even if a later step fails.
  • Public URL reads have no additional tool fee. However, external text sent back to the model adds input tokens, and the model's summary adds output tokens.
  • Search is charged at the cost reported by the search provider. A search can return no useful results and still have a reported charge. The search fee is separate from model token costs; it is not a fixed fee per chat message.
  • Before a search, Niuron checks billing and reserves a conservative $0.02 budget slot. The organization ceiling limits these slots, not total request cost: a $0.04 search ceiling permits at most two dispatched searches, even if the first costs less. Normal settlement releases unused hold value. A ceiling below $0.02 leaves no search slot; the model may explain this limitation instead of searching. LLM costs are not included in that ceiling.
  • BYOK applies to the language model, not the platform search integration. Search still consumes Niuron credits when the model uses your own provider key. The model's own BYOK billing behavior is unchanged.
  • Billing or financial-recording outages prevent paid search dispatch. Missing or ambiguous provider search costs are not guessed and charged. If a reported search cost exceeds its reserved ceiling, customer search fees are capped at that reservation and the result is rejected. A failed final answer does not automatically mean the request had zero cost.

Illustrative example, not a price quote: two model rounds costing $0.004 combined and one search reporting $0.012 consume $0.016 in total. X-Niuron-Tool-Cost-USD reports only 0.012000, not the combined $0.016. The $0.02 reservation is not an extra fee on top of the reported search cost.

Inspect usage and tool execution history

Illustrative response headers, not a guaranteed call count or price
X-Niuron-Request-ID: chatcmpl-example
X-Niuron-Tool-Calls: 2
X-Niuron-Tool-Cost-USD: 0.012000
  • X-Niuron-Request-ID identifies the root API request. Keep it when contacting support or investigating a failure.
  • X-Niuron-Tool-Calls counts attempted model tool calls, including invalid or blocked calls. Zero is possible when the model answers without using tools.
  • X-Niuron-Tool-Cost-USD reports search fees for that request, excluding model token charges. Zero tool fees do not mean zero total cost.
  • The final response's token usage aggregates successful model rounds, rather than only the last answer. Model rounds and dispatched tools have distinct billing IDs and appear as separate usage entries. Their sum, not the tool-cost header alone, represents overall consumption.
  • Settings → Server tools → Load latest 100 tool executions shows dispatched calls, status, hostname, duration, cost and parent request ID. This is organization-scoped. Blocked calls that never reached dispatch may contribute to the header count without appearing as dispatched runs. A run left as started can indicate an interrupted or ambiguous outcome: ask support before repeating a costly request.
  • The tool execution audit does not store search queries, full URL paths/query strings, external response bodies, credentials, prompts or generated answers. This describes the tool audit only, not a global zero-retention policy: chat keeps its normal conversation history, and queries/URLs and tool results are processed by the relevant external providers and model.

Troubleshooting and safe retries

HTTPWhat to check
400Invalid request, unknown tool type, tool disabled for the organization, incompatible domain lists, or mixed Niuron/client/provider tools. Fix settings or the payload; do not retry the same invalid request.
401Missing, invalid or revoked Niuron API key. Check the bearer token; do not use an Exa or model-provider key as your Niuron key.
402Insufficient available credits to reserve the model or search call, or an API-key budget has been exhausted. Check credits and key budgets. Model BYOK does not remove the search-credit requirement.
404The routing profile is not available in this organization, or no eligible model matches the request. Check the profile reference, tool capabilities and organization model restrictions.
429Organization rate or concurrency limit. Respect Retry-After when provided and use bounded backoff; do not immediately flood the service with retries.
502Model/provider execution failed, a model returned incomplete/invalid tool calls, or it exceeded the continuation limit. Preserve the request ID and inspect history before retrying.
503Search is not configured, settings/billing are unavailable, or the tool's financial outcome could not be persisted. Ask the platform operator or support; do not bypass the organization's controls.

Not every failed lookup becomes an HTTP error. A search provider error, blocked URL or exhausted search budget can be returned to the model as a tool result; it may still produce an HTTP 200 answer describing its limitations. HTTP 200 is not proof that every requested lookup succeeded or that no credits were consumed. Treat citations and caveats in the final answer accordingly.

Niuron does not automatically retry paid searches. Your application's retries are new requests and can repeat work and charges. Do not assume replay protection or idempotency for a repeated POST. For an ambiguous timeout or started run, inspect the request history or contact support first.

Use public information, not secrets

Never put passwords, API keys or private conversation data into research instructions or URLs. Tool output is untrusted external content, not an instruction source. Niuron instructs the model to cite sources and ignore external instructions, but this is not an absolute defense against prompt injection or inaccurate answers. Restrict domains for sensitive workloads, verify cited sources and use your own authenticated backend functions for private systems.

where: your backend, with a niuron API key

TypeSafe Jev: decision API

Use POST /v1/systemone to classify messages, choose a category, or score content. Jev takes a state (text, object, or array) and a map of questions, and returns structured decisions — not chat replies or free-form text.

Create your key in /app/api-keys and set NIURON_API_KEY in your backend environment. The Authorization: Bearer header takes this niuron key, not a TypeSafe key. Add credits to your account to make paid calls.

curl
curl https://api.niuron.ai/v1/systemone \
  -H "Authorization: Bearer $NIURON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "jev-latest",
  "state": "My payment failed and I need this resolved today.",
  "questions": {
    "urgent": {
      "type": "noul",
      "instructions": "Does this message express urgency?"
    },
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this?",
      "criteria": {
        "billing": "Payments and refunds",
        "technical": "Bugs and integrations"
      }
    },
    "priority": {
      "type": "score",
      "instructions": "Rate the priority of this request.",
      "criteria": [
        "Low",
        "Medium",
        "High"
      ]
    }
  }
}'
  • noul: a yes/no question. Returns the probability of yes, between 0 and 1, not a boolean. Your code defines the threshold for acting.
  • choice: selects one option from criteria. Returns choice, the probabilities distribution, and confidence.
  • score: evaluates ordered levels in criteria. Returns score, legend, probabilities, and confidence. The score can be fractional; levels start at zero.

Reading the response

Each key in answers matches the key you sent in questions. model identifies the version that evaluated the request; usage reports tokens consumed. Values and usage below are illustrative, not a prediction for your call. Use confidence/probability to decide when to act or request review; a structured decision can still be wrong.

JSON — illustrative response
{
  "model": "jev-1.13.0",
  "answers": {
    "urgent": {
      "type": "noul",
      "noul": 0.95
    },
    "department": {
      "type": "choice",
      "choice": "billing",
      "probabilities": {
        "billing": 0.9,
        "technical": 0.1
      },
      "confidence": 0.8
    },
    "priority": {
      "type": "score",
      "score": 1.8,
      "legend": {
        "0": "Low",
        "1": "Medium",
        "2": "High"
      },
      "probabilities": {
        "0": 0,
        "1": 0.2,
        "2": 0.8
      },
      "confidence": 0.7
    }
  },
  "usage": {
    "input_tokens": 512,
    "output_tokens": 80
  }
}

Available models

Call GET /v1/systemone/models with your niuron key to list decision models and prices. Initially, jev-latest, jev-preview, and jev-1.13.0 resolve to jev-1.13.0 on niuron; these aliases do not automatically track TypeSafe changes. GET /v1/models continues to list chat models, not Jev.

curl
curl https://api.niuron.ai/v1/systemone/models \
  -H "Authorization: Bearer $NIURON_API_KEY"

Billing, BYOK, and limits

  • Initial price: US$0.042 per million input tokens; output tokens are free. Charges use the actual usage returned. During execution, up to US$0.002688 may be temporarily reserved, covering the 64,000-token limit; the difference is released at settlement. Check the model listing for current prices.
  • To use your own TypeSafe account, add its credential to the typesafe provider in the dashboard's providers area. Keep authenticating requests with your niuron key. Your account's BYOK policy applies; do not send the TypeSafe key in the request body.
  • Up to 1 MiB per request and 1–256 questions. Choice accepts 2–255 options; Score accepts 2–10 levels. instructions accepts text, an object, or an array.
  • Model limits: 64,000 tokens for state plus all questions, and 32,000 for state plus the longest question. The provider validates token limits; a request below 1 MiB may still exceed them.
  • Do not use /v1/chat/completions, /v1/responses, or /v1/messages for Jev. This API has no stream, chat messages, images, tools, or auto routing.
  • Make calls from your backend. Never expose your niuron key in public JavaScript, distributed apps, or repositories.

Errors and next steps

HTTPWhat to check
400invalid_provider_key: for BYOK, check your TypeSafe key and its permissions.
401Missing, invalid, or revoked niuron key. Check the authentication header.
402insufficient_credit: top up your niuron balance. guardrail_budget_exceeded: review the key's budget. provider_quota_exceeded: for BYOK, top up your TypeSafe account.
404Decision model unavailable. Check /v1/systemone/models and the model name sent.
413Body exceeds 1 MiB. Reduce the context or split the request.
422Check the JSON, required fields, question types, criteria, and token limits.
429niuron request/concurrency limit or provider rate limit. Honor Retry-After when present and use backoff.
502The provider returned no usable response. The invalid response is not charged to the customer.
503Service, provider, or billing temporarily unavailable. Check error.type; if financial reconciliation is required, follow the guidance below before retrying.
504Provider timeout. niuron does not automatically retry Jev calls to avoid duplicate charges; check the outcome before resending.

Errors include error.type and error.message. Save the X-Niuron-Request-ID header when contacting support. If financial_storage_unavailable says the outcome requires reconciliation, do not automatically retry: contact support with that ID. Platform TypeSafe account failures are treated as unavailability; problems with your BYOK account are identified as yours.

where: your terminal, CLI, or IDE

Coding agents & IDEs

Claude Code uses the Anthropic Messages format and Codex CLI uses Responses. Niuron exposes POST /v1/messages and POST /v1/responses through the shared chat pipeline. The Responses endpoint supports the stateless subset documented above; native-only features and unsupported options are rejected. Other integrations below use /v1/chat/completions with the base URL https://api.niuron.ai/v1.

Claude Code
shell
export ANTHROPIC_BASE_URL=https://api.niuron.ai
export ANTHROPIC_AUTH_TOKEN=ar_live_...
export ANTHROPIC_MODEL=niuron/auto
  • Set ANTHROPIC_AUTH_TOKEN, not ANTHROPIC_API_KEY — the first sends your key as Authorization: Bearer, which is what niuron checks; the second sends x-api-key instead and won't authenticate.
  • ANTHROPIC_MODEL takes any niuron model string, including a routing preset like niuron/auto or niuron/code — same models as the chat completions API, just addressed through Claude Code's own model setting.
  • Claude Code's /model picker won't list niuron's catalog automatically (that needs a GET /v1/models in Anthropic's own shape, not implemented yet) — setting ANTHROPIC_MODEL works regardless, this only affects the picker UI.
Codex CLI
~/.codex/config.toml
model = "niuron/auto"
model_provider = "niuron"

[model_providers.niuron]
name = "niuron"
base_url = "https://api.niuron.ai/v1"
env_key = "NIURON_API_KEY"
wire_api = "responses"
  • wire_api = "responses" is required — Codex dropped Chat Completions support for custom providers in February 2026, so this is the only value that works.
  • env_key names the environment variable Codex reads your niuron API key from — set that variable yourself before running codex.
GitHub Copilot CLI
shell
export COPILOT_PROVIDER_BASE_URL=https://api.niuron.ai/v1
export COPILOT_PROVIDER_API_KEY=ar_live_...
export COPILOT_MODEL=niuron/auto
copilot
  • COPILOT_PROVIDER_BASE_URL/COPILOT_PROVIDER_API_KEY register a custom OpenAI-compatible provider — this is Copilot CLI's own bring-your-own-key path, separate from your GitHub Copilot subscription and billed by niuron instead of GitHub.
  • COPILOT_MODEL takes any niuron model string. Copilot CLI requires the target model to support tool calling and streaming — every niuron model does, through the same chat completions endpoint niuron already exposes.
Cursor
Settings → Models
Base URL:  https://api.niuron.ai/v1
API Key:   ar_live_...
(click Verify)
  • "Override OpenAI Base URL" accepts any base URL, not just api.openai.com — Cursor calls it once to verify before accepting, so the key needs read access to that endpoint too.
  • Type the model name in by hand after verifying (Cursor won't autocomplete niuron's catalog) — any niuron model string works, e.g. niuron/code.
Cline
VS Code → Cline settings
Base URL:  https://api.niuron.ai/v1
API Key:   ar_live_...
Model ID:  niuron/code
  • "OpenAI Compatible", not the default "OpenAI" provider — the default only talks to api.openai.com and ignores a custom base URL.
  • Model ID is optional in Cline's UI, but niuron needs one to route on — set it explicitly (e.g. niuron/code) instead of leaving it blank.
Roo Code
VS Code → Roo Code settings
Base URL:  https://api.niuron.ai/v1
API Key:   ar_live_...
Model:     niuron/code
  • Same "OpenAI Compatible" provider type as its parent project Cline — Settings (gear icon) → Providers → OpenAI Compatible.
  • Roo Code's native tool calling needs the selected model to support OpenAI-style tool calls — every niuron model does, through the same chat completions endpoint.
Kilo Code
VS Code → Kilo Code settings
Base URL:  https://api.niuron.ai/v1
API Key:   ar_live_...
  • Once the base URL and key are set, Kilo Code auto-fetches niuron's model list from /v1/models and offers a searchable picker — no need to type model IDs by hand.
  • The API key field can be left blank only when auth goes through custom headers instead — niuron needs a standard Authorization: Bearer, so fill it in.
Continue.dev
config.yaml
models:
  - name: niuron
    provider: openai
    model: niuron/code
    apiBase: https://api.niuron.ai/v1
    apiKey: ar_live_...
  • provider: openai plus a custom apiBase is what puts Continue.dev in OpenAI-compatible mode — provider stays openai, only apiBase points at niuron.
  • Config lives in config.yaml now — the older config.json format still loads but is deprecated, don't start a new setup there.
Zed
settings.json
{
  "language_models": {
    "openai_compatible": {
      "niuron": {
        "api_url": "https://api.niuron.ai/v1",
        "available_models": [
          { "name": "niuron/auto", "display_name": "niuron", "max_tokens": 128000 }
        ]
      }
    }
  }
}
  • The API key never goes in settings.json — set it in the Agent Panel's provider settings UI, or export it as an env var named after the provider id you pick, uppercased plus _API_KEY (e.g. NIURON_API_KEY for a provider named niuron).
  • max_tokens is required per model or Zed refuses to load it — set it to the real context window of whichever niuron model you list, not a placeholder.
JetBrains AI Assistant
Settings → Tools → AI Assistant
Settings -> Tools -> AI Assistant -> Providers & API keys
Provider:   OpenAI-compatible
Base URL:   https://api.niuron.ai/v1
API Key:    ar_live_...
(Test Connection)
  • This wires up AI Chat only — add the same Base URL and API key again under the separate "AI Completion" settings if you also want inline completions through niuron.
  • Adding the provider doesn't put niuron in front of anything by itself — assign it to a role (core, lightweight, or completion) under "Models Assignment" afterward.
Aider
shell
export OPENAI_API_BASE=https://api.niuron.ai/v1
export OPENAI_API_KEY=ar_live_...
aider --model openai/niuron/code
  • Always prefix the model with openai/ (e.g. openai/niuron/code) — that prefix is what tells Aider's backend to route through the custom OPENAI_API_BASE instead of guessing a provider from the bare model name.
  • The same two variables also work in a project's .env file as AIDER_OPENAI_API_BASE/AIDER_OPENAI_API_KEY, if you'd rather not export them in your shell.
Hermes Agent
~/.hermes/.env
OPENAI_BASE_URL=https://api.niuron.ai/v1
OPENAI_API_KEY=ar_live_...
  • Hermes has three different ways to point at a custom endpoint (the custom-endpoint picker, OPENAI_BASE_URL, and per-provider base URL overrides) — they're not interchangeable. OPENAI_BASE_URL is the simplest match here; it overrides the built-in openai-api provider directly.
  • The model identifier is passed straight through, whatever niuron expects (niuron/auto, niuron/code, ...) — no translation happens on Hermes's side.
where: automatic, on every request

Caching

Two independent layers, both applied before a provider is ever called:

exact-match cache

Byte-identical requests (same tenant, same messages, same routing strategy) return the stored response instead of re-calling a provider. Redis-backed, keyed per request, TTL-bound — the safe default with no accuracy trade-off.

semantic cache

Paraphrased requests that embed close enough (pgvector cosine similarity, 0.95 threshold by default) can hit too — opt-in, since a wrong semantic hit is a wrong answer, not just a slow one. Enabled per deployment, not per request.

Every request's cache outcome (hit or miss, and which layer) is visible per row in request history, and rolled up as a hit rate on the overview.

where: /app and /app/requests

Observability

/app — overview

Rolled-up stats: total requests, cache hit rate, p95 latency, and cost, with an hourly trend chart.

/app/requests — request log

Every request, one row each: requested vs. selected model, provider, cache hit/type, latency, actual cost, routing score, and status. This is where an API call and a chat playground message both land — same pipeline, same log.

where: /app/settings, /app/api-keys, /app/providers, /app/billing

Account management

/app/api-keys

Create and revoke API keys — the secret is shown once, at creation. This is what authenticates every /v1/chat/completions call.

/app/providers

See which providers are enabled, and register credentials — scoped to your tenant, or shared as a default.

/app/billing

Buy prepaid USD credits through Stripe Checkout with Adaptive Pricing. Prices use a BRL base compatible with our Brazilian account; Stripe presents available payment currencies and the final total. BCB PTAX defines the BRL base price for USD credits. Automatic top-ups use the saved currency, not Checkout Adaptive Pricing. Balances and usage remain in USD.

Nothing here needs reading before you can try it.