Authentication
Two distinct kinds of keys, with different threat models and different homes.
useLLM has two kinds of API keys. They live in different places and protect different things, so it's worth keeping them straight before anything else.
| Gateway key | Provider key | |
|---|---|---|
| Prefix | ul_live_* | sk-proj-* / sk-ant-* |
| Issued by | useLLM (you generate it on /api-keys) | OpenAI / Anthropic |
| Lives in | Your application code or secret manager | Only useLLM (encrypted at rest) |
| Used to authenticate | App → useLLM gateway | useLLM gateway → OpenAI / Anthropic |
| Storage in our DB | SHA-256 hash only — the raw secret never persists | AES-256-GCM ciphertext, decrypted in-process per request |
| If compromised | Revoke from /api-keys; instant 401s for the leaked secret | Rotate at the provider; re-paste the new one on /providers |
Gateway keys
Every request to api.usellm.io needs an Authorization: Bearer ul_live_… header. Issue keys from /api-keys and store them in your secret manager. The full secret is shown once on creation — we only retain a SHA-256 hash for lookup, so a leaked database doesn't leak active keys.
curl https://api.usellm.io/v1/chat/completions \
-H "Authorization: Bearer ul_live_XXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "model": "gpt-4o-mini", "messages": [...] }'Provider keys
Connect provider keys on /providers. On save we probe the key against the provider once so you find out immediately if it's rejected. After that the key sits encrypted in Postgres — decryption happens only in-process when forwarding a request, never written back to disk.
- OpenAI keys → header
Authorization: Bearer …toapi.openai.com. - Anthropic keys → header
x-api-key: …toapi.anthropic.com. The gateway also rewrites OpenAI-style messages into Anthropic'ssystem + messagesshape transparently.
Rotating a provider key
- Generate a fresh key at the provider's dashboard.
- Paste it into a new connection on /providers (e.g. name it
production-2). Verify it showsVerified. - Optionally wait for traffic to switch over (the gateway picks the most recently active connection per provider — see Routing).
- Revoke the old connection. No app redeploy needed.