Skip to main content

OpenRouter

An OpenRouter connection reaches https://openrouter.ai/api/v1, a single OpenAI-compatible endpoint that routes to hundreds of models across dozens of upstream providers. Most of what it is good for costs nothing: comparing models by price, context length and capability, checking which providers serve a given model, and reading back exactly what a completion cost after the fact. Running the completion itself is the one action that spends money, so it starts switched off and asks a human every time.

What you need

An OpenRouter API key. That is a static credential, so this connector works end to end today: you paste the key once and the gateway seals it.

  1. Open openrouter.ai/keys and choose Create Key.
  2. Give it a name, and set a credit limit while you are there. An ordinary inference key is not scoped by endpoint, so the credit limit is the real least-privilege control: it caps what this connection can ever spend, independently of anything Permaura enforces. Set it to what you would be relaxed about losing.
  3. Copy the key. OpenRouter shows it once.

Permaura sends it as Authorization: Bearer <your-key>, so paste it exactly as OpenRouter gave it to you.

One key cannot do both jobs

credits.read calls GET /credits, which OpenRouter restricts to a management key — and management keys cannot make completion calls at all. With a normal inference key that one action returns 401 and everything else works. If you want account-wide credit reporting, add a second connection sealed with a management key and grant it only that action. For per-key spend, key.read already reports limit, limit_remaining and usage, and it works with the inference key.

Add the connection

In the console, open Access → Connections → Add connection and pick OpenRouter from the catalog. Paste the API key when the form asks for the credential. It is sealed on your gateway at that moment and never displayed again, and from then on Permaura injects it server-side on each approved call.

Adding the connection makes these actions possible, not permitted. An agent cannot touch any of them until a grant allows it.

What the agent can do

Capabilities are namespaced under the connection id, so an agent sees models.list as <connection>.models.list.

ActionWhat it doesOn by default
models.listLists models with pricing and context length; filter with q, category, sort, limit, offset, supported_parametersYes
models.readReads one model by author and slugYes
models.endpointsLists the provider endpoints serving a model, with each one's price and limitsYes
providers.listLists the upstream providers OpenRouter routes toYes
generation.readReads cost, token counts and routing metadata for one generation, by idYes
key.readReads the current key's label, spend limit, remaining limit and usageYes
credits.readReads total credits purchased and used — management key only, see aboveYes
chat.completions.createRuns a chat completionNo, and it asks for approval

A completion spends credit the moment it runs, and a careless model choice can be a hundred times dearer than a careful one for the same prompt. That is why it stays off until you switch it on, and prompts you every time even then.

The pairing worth setting up is models.list plus chat.completions.create: the agent can survey what is available and what it costs on its own, and you see the model it settled on in the approval prompt before anything runs.

Good to know

  • The host is pinned. Every call goes to openrouter.ai and nowhere else, whatever an agent asks for.
  • Only the listed inputs reach OpenRouter. chat.completions.create forwards model, models, messages, provider, temperature, max_tokens, top_p, stop, response_format, tools, tool_choice and reasoning. Anything else an agent sends is dropped before the request leaves your gateway.
  • Streaming is deliberately not forwarded. stream is not on that list, so every completion comes back as one response. A gateway call is request and response; a token stream has nowhere to go.
  • Costs are knowable after the fact. Every completion response carries an id; hand it to generation.read and you get the real total_cost, token counts, which provider served it and how long it took. This is the cheapest audit trail there is for what an agent has been spending.
  • Credit limits and rate limits are different things. Running out of credit returns 402; going too fast returns 429. Free model variants (ids ending :free) carry their own per-minute and per-day request caps, which rise once you have bought credits; OpenRouter publishes the current figures on its limits page. Extra keys do not help — OpenRouter governs capacity per account, not per key.
  • There is no sandbox. The :free model variants are the closest thing: real routing, no credit spent, tight daily caps. Point a test agent at one of those first.
  • OAuth is not offered here, on purpose. OpenRouter has a PKCE sign-in flow, but it hands back an ordinary API key rather than an OAuth access token and has no client registration, so there is nothing a standard OAuth connection could hold. Paste a key.