omni-api-keys — Claude Code skill: manage Anthropic keys
This skill creates, lists, rotates and revokes Anthropic API keys, and sets per-key scopes and limits. Useful when keys are handed out from inside an agent.
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a claude-codeWhat omni-api-keys does
The skill covers the whole key lifecycle on Anthropic: create, list, update, regenerate, revoke. It also grants a key access to specific models and combos, and shows which devices have used that key.
Under the hood it calls a local API at http://localhost:20128. Listing keys goes through GET /api/keys, creation through POST /api/keys, and model access changes atomically via POST /api/keys/{id}/access. A separate set of endpoints handles key groups and their permissions.
Every request needs a Bearer token, obtained with POST /api/auth/login, or REQUIRE_API_KEY=false for local development. If a key allows all models or all combos, adding new ones through /access requires switchToRestricted: true — otherwise you get a 409 Conflict. Concurrent PATCH /api/keys/{id} calls overwrite the policy entirely outside that lock, so keep it in mind when something besides the agent edits keys.
What it helps with
- issue a key for a new service and limit it to certain models
- check which keys are currently active
- revoke a key that leaked
- regenerate a key without losing its settings
- group keys under shared permissions
Example prompts for the agent
- List the Anthropic API keys
- Create a new key and allow it only the gpt-4o model
- Revoke the key with id
abc123
How to install omni-api-keys
1Skills CLI (Vercel)
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a claude-code2Manually: put the files in place
~/.claude/skills/omni-api-keys/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/omni-api-keys/
1Skills CLI (Vercel)
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a codex2Manually: put the files in place
.agents/skills/omni-api-keys/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a cursor2Manually: put the files in place
.cursor/skills/omni-api-keys/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install cheaper-inference/OmniRoute omni-api-keys2Manually: put the files in place
.github/skills/omni-api-keys/SKILL.md1Skills CLI (Vercel)
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a gemini-cli2Platform CLI
gemini skills install https://github.com/cheaper-inference/OmniRoute --path skills/omni-api-keysManually: put the files in place
.devin/skills/omni-api-keys/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about omni-api-keys
How do I install omni-api-keys in Claude Code?
Run npx skills add cheaper-inference/OmniRoute --skill omni-api-keys -a claude-code. The skill then lands at ~/.claude/skills/omni-api-keys/SKILL.md.
What does omni-api-keys do?
It creates, lists, updates, regenerates and revokes Anthropic API keys, and controls their model access, spending limits and expiration.
What do I need before using it?
A Bearer token from POST /api/auth/login, or REQUIRE_API_KEY=false for local development. Requests go to http://localhost:20128.
Source text
SKILL.md · MIT
---
name: omni-api-keys
description: Create, list, rotate, and revoke OmniRoute API keys. Control per-key scopes, spending limits, and expiration. Keys gate access to all proxy and management endpoints.
---
<!-- generated by src/lib/agentSkills/generator.ts; manual edits will be overwritten -->
## Overview
Create, list, rotate, and revoke OmniRoute API keys. Control per-key scopes, spending limits, and expiration. Keys gate access to all proxy and management endpoints.
## Authentication
All requests require a valid Bearer token or session cookie. Obtain a token via `POST /api/auth/login` or configure `REQUIRE_API_KEY=false` for local development.
## Endpoints
### GET /api/keys
List API keys
```bash
curl http://localhost:20128/api/keys \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys
Create API key
```bash
curl -X POST http://localhost:20128/api/keys \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### GET /api/keys/{id}
Get API key
```bash
curl http://localhost:20128/api/keys/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### PATCH /api/keys/{id}
Update API key
```bash
curl -X PATCH http://localhost:20128/api/keys/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### DELETE /api/keys/{id}
Delete API key
```bash
curl -X DELETE http://localhost:20128/api/keys/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys/{id}/access
Add or remove allowed models and combos on an API key atomically
Adds or removes allowed models and combos on an API key without lost updates.
Serialized per key ID using an in-process async lock.
Keys allowing all models (modelAccessMode: all) or all combos (allowedCombos containing 'combo/*')
require switchToRestricted: true when adding new models or combos, otherwise returning a 409 Conflict.
When switching to restricted mode, the allowlist becomes exactly the net added items (at least one required).
Direct concurrent PATCH calls to /api/keys/{id} completely overwrite the policy outside this lock.
```bash
curl -X POST http://localhost:20128/api/keys/{id}/access \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### GET /api/keys/{id}/devices
List devices for an API key
Lists the distinct devices (masked IP + User-Agent fingerprints) tracked for an API key by the in-memory device tracker. IPs are masked before storage; the route never sees the raw client IP.
```bash
curl http://localhost:20128/api/keys/{id}/devices \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys/{id}/regenerate
POST keys › <id> › regenerate
```bash
curl -X POST http://localhost:20128/api/keys/{id}/regenerate \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### GET /api/keys/{id}/reveal
GET keys › <id> › reveal
```bash
curl http://localhost:20128/api/keys/{id}/reveal \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### GET /api/keys/{id}/usage-limits
GET keys › <id> › usage limits
```bash
curl http://localhost:20128/api/keys/{id}/usage-limits \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### GET /api/keys/groups
GET keys › groups
```bash
curl http://localhost:20128/api/keys/groups \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys/groups
POST keys › groups
```bash
curl -X POST http://localhost:20128/api/keys/groups \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### GET /api/keys/groups/{id}
GET keys › groups › <id>
```bash
curl http://localhost:20128/api/keys/groups/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### PUT /api/keys/groups/{id}
PUT keys › groups › <id>
Updates the group. Setting isActive to false pauses its allow rules while preserving membership restrictions and deny rules. Other active groups may still grant access unless a deny matches. Keys belonging only to inactive groups have no group grants. Keys without groups remain unrestricted by group policy; per-key restrictions still apply.
```bash
curl -X PUT http://localhost:20128/api/keys/groups/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### DELETE /api/keys/groups/{id}
DELETE keys › groups › <id>
```bash
curl -X DELETE http://localhost:20128/api/keys/groups/{id} \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### GET /api/keys/groups/{id}/keys
GET keys › groups › <id> › keys
```bash
curl http://localhost:20128/api/keys/groups/{id}/keys \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys/groups/{id}/keys
POST keys › groups › <id> › keys
```bash
curl -X POST http://localhost:20128/api/keys/groups/{id}/keys \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### DELETE /api/keys/groups/{id}/keys
DELETE keys › groups › <id> › keys
```bash
curl -X DELETE http://localhost:20128/api/keys/groups/{id}/keys \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### GET /api/keys/groups/{id}/permissions
GET keys › groups › <id> › permissions
```bash
curl http://localhost:20128/api/keys/groups/{id}/permissions \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
### POST /api/keys/groups/{id}/permissions
POST keys › groups › <id> › permissions
```bash
curl -X POST http://localhost:20128/api/keys/groups/{id}/permissions \
-H "Authorization: Bearer $OMNIROUTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
```
### DELETE /api/keys/groups/{id}/permissions
DELETE keys › groups › <id> › permissions
```bash
curl -X DELETE http://localhost:20128/api/keys/groups/{id}/permissions \
-H "Authorization: Bearer $OMNIROUTE_TOKEN"
```
## Payloads
See the full OpenAPI specification at `GET /api/openapi/spec` or `docs/openapi.yaml` for detailed request/response schemas.
© cheaper-inference · MIT · cheaper-inference/OmniRoute