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.
- Open openrouter.ai/keys and choose Create Key.
- 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.
- 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.
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.
| Action | What it does | On by default |
|---|---|---|
models.list | Lists models with pricing and context length; filter with q, category, sort, limit, offset, supported_parameters | Yes |
models.read | Reads one model by author and slug | Yes |
models.endpoints | Lists the provider endpoints serving a model, with each one's price and limits | Yes |
providers.list | Lists the upstream providers OpenRouter routes to | Yes |
generation.read | Reads cost, token counts and routing metadata for one generation, by id | Yes |
key.read | Reads the current key's label, spend limit, remaining limit and usage | Yes |
credits.read | Reads total credits purchased and used — management key only, see above | Yes |
chat.completions.create | Runs a chat completion | No, 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.aiand nowhere else, whatever an agent asks for. - Only the listed inputs reach OpenRouter.
chat.completions.createforwardsmodel,models,messages,provider,temperature,max_tokens,top_p,stop,response_format,tools,tool_choiceandreasoning. Anything else an agent sends is dropped before the request leaves your gateway. - Streaming is deliberately not forwarded.
streamis 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 togeneration.readand you get the realtotal_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
:freemodel 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.