Skip to main content
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:
  1. Validates the virtual key
  2. Loads the key’s budget, rate limits, and policies
  3. 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?

ProblemVirtual key solution
Sharing one API key across the teamIssue one virtual key per developer or CI job
No visibility into who spent whatEvery request is attributed to the key (and its owner)
Can’t disable a single developerRevoke or pause one key without touching others
Budget leaks discovered in billingHard limit enforced before the request is forwarded

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
  • Model allowlist — optional list of permitted models; all others return 403
  • Policies — which guardrail policies apply to this key
  • Owner — the user the key is attributed to in analytics

Creating a key

Dashboard

Console → Keys & Limits → Create key. Set a name, budget, and any rate limits. The key is shown once at creation — store it.

REST API

curl -X POST https://api.wardin.ai/v1/keys \
  -H "Authorization: Bearer wardin_sk_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "alice-dev",
    "monthlyBudgetUsd": 50,
    "rpmLimit": 60,
    "tpmLimit": 100000
  }'
Response:
{
  "id": "key_01j...",
  "name": "alice-dev",
  "key": "wardin_sk_abc123...",
  "monthlyBudgetUsd": 50,
  "currentSpendUsd": 0,
  "createdAt": "2025-01-15T10:00:00Z"
}
The key field is only returned at creation time. It cannot be retrieved again — store it securely.

Key lifecycle

active → paused → active   (manual toggle)
active → budget_exceeded   (automatic, resets monthly)
active → revoked           (permanent)
A key in budget_exceeded state returns:
{
  "error": {
    "type": "budget_exceeded",
    "message": "Monthly budget of $50.00 has been reached.",
    "code": 429
  }
}

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