BUZZ AI Gateway
Docs · Guides · Authentication

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

HeaderNotesSDK 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.

The 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 / SDKDefault auth headerRecommended on BUZZ
Anthropic Python / Node SDKx-api-keyUse SDK default unchanged
OpenAI Python / Node SDKAuthorization: BearerUse SDK default unchanged (target /v1/chat/completions)
Google GenAI SDKx-goog-api-keyUse SDK default unchanged
Claude Code CLIenv ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URLSee Claude Code guide
curl / custom clientn/aAuthorization: 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

FieldTypeWhat it does
namestringHuman label, max 50 characters. Used in the dashboard list and search.
expired_timeint (unix sec)Hard expiration. Use -1 for never expires.
unlimited_quotaboolIf true, the key has no spend cap. If false, you set remain_quota.
remain_quotaintRemaining spend allowance. Required and must be ≥ 0 when unlimited_quota is false.
model_limits_enabledboolToggle per-key model whitelisting.
model_limitsstringComma-separated list of model IDs the key may call. Empty means all models in the assigned group.
allow_ipsstring | nullNewline-separated IP allow-list. Empty / null means no IP restriction.
groupstringDefault upstream channel group used when routing requests.
vendor_routesJSON stringOptional per-vendor group override, e.g. {"claude":"aws","openai":"gpt-direct"}. Empty falls back to group.

Status values

CodeMeaning
1Enabled — accepts requests
2Disabled — manually paused
3Expired — past expired_time
4Exhausted — 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

Don't commit .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

HTTPerror.typeCauseFix
401buzz_errorMissing or invalid API keyRe-export BUZZ_API_KEY; double-check no stray quotes; confirm the key still exists in the dashboard.
403permission_errorIP not on the key's allow-list, or the key was disabledUpdate allow_ips, or re-enable the key (status 1).
403permission_errorGroup / model not allowed for this keyEither 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