Authentication
Every request to /v1/* needs an API key. BUZZ accepts three header forms, so the official Anthropic, OpenAI, and Google GenAI SDKs all work without code changes — point the SDK at https://buzzai.cc and your existing auth setup keeps running.
Three accepted header forms
| Header | Notes | SDK alignment |
|---|---|---|
Authorization: Bearer <KEY> |
The recommended default. Used across the BUZZ REST surface. | OpenAI SDK default. Anthropic SDK accepts it when set explicitly. |
Authorization: Bearer sk-<KEY> |
The sk- prefix is automatically stripped server-side. |
Useful when reusing infrastructure that expects an sk--style key. |
x-api-key: <KEY> |
Drop-in compatible with the Anthropic SDK default header. | Anthropic SDK default. |
x-goog-api-key: <KEY> |
Accepted on Google GenAI compatibility paths so the official Gemini SDK can target BUZZ unchanged. | Google GenAI SDK default. |
Pick whichever lines up with the SDK you already use. All four headers resolve to the same key lookup — there is no behavioral difference once authenticated.
anthropic-version header is optional on BUZZ. When omitted, BUZZ defaults it to 2023-06-01 before forwarding upstream. Send it explicitly if you want your code to stay portable to direct Anthropic, which does require it.
Which header should I use?
Match the header to the SDK you are calling, so you do not need to monkey-patch its request layer.
Anthropic SDK
The official anthropic Python and @anthropic-ai/sdk Node packages send x-api-key by default. Just point them at BUZZ:
from anthropic import Anthropic
client = Anthropic(
base_url="https://buzzai.cc",
api_key="",
)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://buzzai.cc",
apiKey: process.env.BUZZ_API_KEY,
});
OpenAI SDK (against /v1/chat/completions)
The OpenAI SDK sends Authorization: Bearer ... by default. Use it against the OpenAI-compatible /v1/chat/completions path:
from openai import OpenAI
client = OpenAI(
base_url="https://buzzai.cc/v1",
api_key="",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "ping"}],
)
Google GenAI SDK
The official google-genai SDK sends x-goog-api-key. BUZZ recognizes that header on its Gemini-compatible paths, so you can point the SDK at BUZZ and reuse a BUZZ key for Gemini-compatible models exposed by the gateway.
curl / custom HTTP client
For raw HTTP calls, Authorization: Bearer is the path of least resistance — it matches the rest of the BUZZ REST surface, including non-relay endpoints like billing.
curl -X POST https://buzzai.cc/v1/messages \
-H "Authorization: Bearer $BUZZ_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{ "model": "claude-haiku-4-5-20251001", "max_tokens": 32, "messages": [{"role":"user","content":"ping"}] }'
SDK header cheatsheet
| Tool / SDK | Default auth header | Recommended on BUZZ |
|---|---|---|
| Anthropic Python / Node SDK | x-api-key | Use SDK default unchanged |
| OpenAI Python / Node SDK | Authorization: Bearer | Use SDK default unchanged (target /v1/chat/completions) |
| Google GenAI SDK | x-goog-api-key | Use SDK default unchanged |
| Claude Code CLI | env ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL | See Claude Code guide |
| curl / custom client | n/a | Authorization: Bearer <KEY> |
API key management
Keys are managed from the Tokens page in the dashboard. You can also drive the same operations programmatically via /api/token/* using a session or access token (separate from the sk- relay key).
Fields you can set per key
| Field | Type | What it does |
|---|---|---|
| name | string | Human label, max 50 characters. Used in the dashboard list and search. |
| expired_time | int (unix sec) | Hard expiration. Use -1 for never expires. |
| unlimited_quota | bool | If true, the key has no spend cap. If false, you set remain_quota. |
| remain_quota | int | Remaining spend allowance. Required and must be ≥ 0 when unlimited_quota is false. |
| model_limits_enabled | bool | Toggle per-key model whitelisting. |
| model_limits | string | Comma-separated list of model IDs the key may call. Empty means all models in the assigned group. |
| allow_ips | string | null | Newline-separated IP allow-list. Empty / null means no IP restriction. |
| group | string | Default upstream channel group used when routing requests. |
| vendor_routes | JSON string | Optional per-vendor group override, e.g. {"claude":"aws","openai":"gpt-direct"}. Empty falls back to group. |
Status values
| Code | Meaning |
|---|---|
| 1 | Enabled — accepts requests |
| 2 | Disabled — manually paused |
| 3 | Expired — past expired_time |
| 4 | Exhausted — remain_quota hit zero (only when unlimited_quota is false) |
Lifecycle: create, retrieve, rotate, delete
Create
The dashboard form (or POST /api/token/) creates a key. The full key is generated server-side; the create response does not echo it. To retrieve the full key after creation, use the dashboard copy button or call POST /api/token/<id>/key. List endpoints only show a masked form like OnyH**********esAm.
Retrieve
Treat the full key as a one-time secret. Copy it once, store it in your secret manager or environment, and never paste it back into the dashboard or chat.
Rotate
To rotate, create a new key, deploy it everywhere your apps use the old one, then delete the old key. There is no in-place key regeneration; you delete and create.
Delete
Soft-delete is supported: DELETE /api/token/<id>. For batch removal, post an array of IDs to POST /api/token/batch with body {"ids":[1,2,3]}.
Security best practices
- Use environment variables, not hard-coded literals. Read the key from
BUZZ_API_KEY(or whatever name your project uses) at startup. Never paste a key into source control, dashboards, screenshots, or chat tools. - Add the key to
.gitignore-tracked files only. Common safe locations:.env, secret managers (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault), CI/CD secret stores. Make sure.envis gitignored. - Scope per project, not per organization. Create a separate key per service or environment (dev / staging / prod). It limits blast radius if one leaks and makes rotation cheap.
- Set an IP allow-list when you can. If your workload runs from known egress IPs (production servers, CI runners, NAT gateways), populate
allow_ips. This converts a leaked key from "anyone with HTTP" to "anyone on those IPs". - Use
model_limitsfor high-risk keys. Restricting a key toclaude-haiku-4-5-20251001caps the per-call cost even if abused. - Set an expiration. Keys for short-lived prototypes, demos, or contractor handoffs should have a hard
expired_time.-1is convenient but easy to forget. - Rotate on a schedule. Long-lived production keys should rotate at least every 90 days, or immediately on any suspected exposure (CI log leak, accidentally pushed commit, departed team member).
- Watch usage for anomalies. Use
GET /api/usage/token/with the key itself as auth to read remaining quota and recent spend. Alert on unexpected spikes. - If a key leaks, delete it first, investigate second. Soft-delete via the dashboard is immediate. Then create a replacement, redeploy, and only then audit logs to understand what happened.
.env. Add .env and any local secret file to .gitignore before your first commit. Use .env.example with placeholder values to document required variables.
Authentication errors
| HTTP | error.type | Cause | Fix |
|---|---|---|---|
| 401 | buzz_error | Missing or invalid API key | Re-export BUZZ_API_KEY; double-check no stray quotes; confirm the key still exists in the dashboard. |
| 403 | permission_error | IP not on the key's allow-list, or the key was disabled | Update allow_ips, or re-enable the key (status 1). |
| 403 | permission_error | Group / model not allowed for this key | Either change the key's group / model_limits, or call a permitted model. |
BUZZ-side errors use the envelope:
{
"error": {
"type": "buzz_error",
"message": "Invalid token... (request id: 202605260713594...)"
}
}
Anthropic-passthrough errors retain the official shape with request_id at the top level.
See also
- Quickstart — five-minute first call.
- POST /v1/messages — full request/response reference.
- GET /api/token/ — programmatic key management.
- Error handling — retry policies and the BUZZ-specific 503 case.