Skip to main content
The llm primitive is a full wrapper over OpenRouter. It gives your agent a single, OpenAI-compatible chat-completions endpoint that routes to 300+ models across Anthropic, OpenAI, Google, Meta, Mistral, and more — with provider routing, fallbacks, and streaming. You don’t manage an OpenRouter account or key: Naive holds the key and bills each call in Naive credits based on the exact cost OpenRouter returns. There are two ways to use it:
  1. The typed primitivenaive.llm.chat() / naive.llm.stream() / naive.llm.models() in the SDK (plus CLI, MCP, and the agent toolset).
  2. The drop-in proxy — point any OpenAI or OpenRouter client’s baseURL at Naive and keep your existing code.
Both are OpenAI/OpenRouter-shaped. There is no Anthropic Messages API here, and it is not a coding agent’s model endpoint.POST /v1/messages is not mounted and answers 404. A client that speaks the Anthropic Messages shape — Claude Code, the Claude Agent SDK, anything driven by ANTHROPIC_BASE_URL — cannot be repointed at Naive. The blocker is the request shape, not streaming: every route on this page streams, and stream: true pipes the provider’s SSE stream straight through (see Streaming). Anthropic models are reachable here the same way every other provider’s are — as an OpenRouter model id such as anthropic/claude-sonnet-4.6 in an OpenAI-shaped request.Do not route a coding agent’s own reasoning loop through Naive even where the shape does match. Every token of every turn would settle against your credit balance at provider cost plus markup, for an extra network hop and worse latency, to obtain what talking to the provider directly already gives you. Use the llm primitive for the inference your agent performs on a customer’s behalf, where the per-tenant metering, budget caps and audit trail are the point. Naive is the layer an agent calls; it is not the endpoint an agent runs on.

CLI First

Endpoints

The request and response bodies are exactly OpenRouter’s (which are in turn OpenAI-compatible) — Naive forwards them through. See OpenRouter’s API reference for the full schema.

Chat completions

Response (OpenAI-shaped, plus credits_used):

Key parameters

Provider routing & fallbacks

Because the body is OpenRouter’s, you get its routing controls for free:

Streaming

Streaming is Server-Sent Events. The final chunk carries the usage object (including cost); Naive bills it after the stream closes.

Use Naive instead of OpenRouter (drop-in proxy)

If you already use the OpenAI or OpenRouter SDK, you don’t need to change your code — just change the baseURL and key. Naive injects the OpenRouter key server-side and bills your credits.
The proxy is a transparent passthrough: every path under /v1/proxy/openrouter/* maps to https://openrouter.ai/api/v1/* (so chat/completions, models, generation, etc. all work). It is authenticated by your Naive api key and is not Account-Kit gated — use the typed /v1/llm routes when you want per-tenant AccountKit enforcement.

Multi-tenant

Like other primitives, the typed routes are AccountKit-gated and per-user:
Toggle the llm primitive on/off per Account Kit in the dashboard (Account Kits → Primitives → Generation), or via primitives_config.llm.enabled. See Account Kits.

Billing

Naive bills the exact cost OpenRouter reports for each request (usage.cost, in USD) times a small markup, converted to credits ($0.05 = 1 credit). There’s no per-model rate table to keep in sync — token-heavy models simply cost more. Costs are charged after the response completes (after the final chunk, for streams). Listing models is free. See Credits.

Agent tools

The llm primitive is part of agentTools(): the model can route its own sub-calls with naive_run_primitive(primitive: "llm", method: "chat", arguments: { model, messages }), or list models with method: "models".

Error Handling