A virtual key is what your code authenticates with when calling the Wardin gateway. It looks like wardin_sk_abc123... and is never a real Anthropic or OpenAI key.
When a request arrives, Wardin:
- Validates the virtual key
- Loads the key’s budget and rate limits, plus the tenant’s policies
- Swaps in the real provider credential before forwarding the request
Your actual provider API keys never leave Wardin’s control plane — your code never touches them.
Why virtual keys?
Key properties
Each virtual key has:
- Monthly budget — hard spend ceiling in USD (enforced via Redis before forwarding)
- RPM limit — requests per minute cap
- TPM limit — tokens per minute cap
- Key class —
interactive (developer) or ci (headless), set at creation; CI keys get their own budget pool
- Owner — the user the key is attributed to in analytics
- Team (cost center) — which team the key’s spend bills to on the LEDGER. Independent of owner: defaults to the owner’s team at creation, but is overridable — so a key can be owned by one person and billed to another team (cross-charge), or have a team with no human owner at all (CI/service keys)
Creating a key
Console
Console → Keys & Limits → Create key. Set a label, budget, and any rate limits. The key is shown once at creation — store it.
REST API
Response:
The rawKey field is only returned at creation time. It cannot be retrieved again — store it securely.
See the full endpoint reference: POST /v1/keys — all fields, validation, and error responses.
Key lifecycle
A key in budget_exceeded state returns:
Security recommendations
- Issue separate keys for each developer and each CI environment
- Set conservative budgets; raise them via budget increase requests
- Register
wardin_sk_ with your secret scanner (GitHub Advanced Security, truffleHog, etc.)
- Rotate keys periodically — revoke the old one, issue a new one
- Never commit virtual keys to version control