anoman
Docs · Authentication

API keys and authentication.

Anoman keys are bearer tokens passed in the Authorization header. They are scoped per customer, tied to a tier, and rotatable from the dashboard.

Key format

Anoman API keys

Every key starts with the prefix anm-sk- followed by 40+ characters of base64-encoded random bytes.

Example key

anm-sk-Mh4uZf2W8Rk1JtX9...
  • The raw key is shown exactly once at creation — copy it immediately.
  • We store only a bcrypt hash. Lost keys cannot be recovered — issue a new one.
  • Keys are scoped per API key row, not per customer. One customer can have many keys with different tiers, budgets, and policies.
  • Keys live in app.anoman.io/dashboard/keys.

Header format

Authorization: Bearer

Pass the key in the standard OAuth 2.0 bearer header. The OpenAI and Anthropic SDKs do this automatically when you set their api_key parameter.

curl https://api.anoman.io/v1/chat/completions \
  -H "Authorization: Bearer anm-sk-..." \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Hi"}]}'
Compatibility note. Anoman accepts the x-api-key header too (for Anthropic SDK compatibility on the /anthropic/ endpoint). Bearer is preferred everywhere else.

Authentication errors

When auth fails

All authentication failures return HTTP 401 or 403 with a JSON body matching the shape below. The code field distinguishes the failure type so you can branch your client-side handling.

{
  "error": {
    "type": "invalid_request_error",
    "code": "auth_invalid",
    "message": "Invalid API key. Get one at https://app.anoman.io/dashboard/keys"
  }
}
HTTPCodeCause
401auth_missingNo Authorization header sent
401auth_invalidKey is malformed or unknown
403auth_revokedKey was revoked from the dashboard
402budget_exceededMonthly budget hit. Top up or wait for cycle reset.

See the full error code reference for non-auth failure modes.

Best practices

Storing and rotating keys

Treat your Anoman key like an OAuth bearer — anyone with the key can spend your budget. Load from a secret manager or environment variable; never commit to source control.

import os
from openai import OpenAI

# Read from env at startup. Fail fast if absent.
api_key = os.environ.get("ANOMAN_API_KEY")
if not api_key:
    raise RuntimeError("ANOMAN_API_KEY must be set")

client = OpenAI(base_url="https://api.anoman.io/v1", api_key=api_key)

Recommended scoping pattern

  • One key per environment — separate development, staging, production keys so you can revoke a leaked dev key without impacting prod.
  • One key per service if your stack has multiple call sites (web backend, batch worker, etc.). Lets you attribute usage in traces and revoke surgically.
  • Per-key budget — set a monthly USD cap on each key in the dashboard. A runaway script then hits 402 instead of draining your account.

Rotation

  1. Create a new key in the dashboard (existing keys stay live).
  2. Deploy the new key to your service env var.
  3. Revoke the old key once you confirm zero traffic on it (visible in last_used_at).

Leak response

If a key is exposed (committed to GitHub, posted in a screenshot, etc.):

  1. Revoke immediately via the dashboard — takes effect within 60 seconds.
  2. Issue a replacement key.
  3. Audit the trace log for unexpected usage in the window between leak and revocation.
  4. Reach out at [email protected] if you suspect abuse — we can correlate with our internal logs.

Need a key?

Free to create. No card required.