BYOK — Bring Your Own Key
Use Sonzai's hosted infrastructure but bill provider tokens to your own account. Per-project, per-provider, encrypted at rest.
BYOK lets you keep using Sonzai's chat / sessions / extraction stack while routing the underlying provider call through your API key. Token charges land on your provider invoice; everything else (memory, personality, post-processing models, billing for Sonzai's platform) behaves the same.
This is different from Custom LLM (BYOM). BYOK uses Sonzai's first-party provider integrations with your billing key; BYOM swaps the entire chat-completion call to an endpoint you host.
Scope
BYOK keys are stored per (project, provider). There is one key per provider per project, no per-agent / per-session / per-call BYOK keys. That makes the mental model simple: any chat turn that lands on a given provider in a given project routes through that project's BYOK key for that provider, regardless of which agent or session triggered it.
| What | Scope |
|---|---|
| Storage | per (project_id, provider) — primary key in the table |
| Resolution at request time | by project_id of the chat call → look up key for the resolved provider |
| Encryption | AES-256 at rest, decrypted only inside the request path |
| API access | tenant-level API keys may manage any project they own; project-scoped keys must match the requested project_id exactly |
If you want different keys for different agents in the same project, use separate projects — that's the only knob.
Setup paths
Two ways to add a key, both equivalent on the wire:
1. Dashboard
The fastest path for a one-off setup or rotation.
- Open platform.sonz.ai and pick the project.
- Go to Settings → BYOK.
- Each of the four supported providers shows a card. Pick the one you want to configure.
- Paste the API key from the provider (OpenAI, Google AI Studio for Gemini, xAI console, OpenRouter dashboard).
- Hit Save. The dashboard runs the same synchronous probe the API does — if the upstream rejects the key, the save fails and you get the provider's error message inline. No bad key gets persisted.
- Once saved the card switches to the configured state — redacted
prefix, health badge (
healthy/unhealthy/unknown), and buttons to Replace, Test, Disable, or Delete.
The dashboard is the same endpoint the SDK calls, so anything you do there is identical to what you can script.
2. API / SDK
Useful for IaC, CI bootstrap of new tenants, key rotation cron jobs, or provisioning during automated tenant onboarding. Endpoints documented below.
What you can plug in
The same providers the platform speaks natively:
openaigeminixaiopenrouter(internal fallback path — a key here covers when the platform falls through to OpenRouter)
A custom BYOM endpoint isn't a BYOK provider; configure it via
Custom LLM instead.
Storage and security
- Keys are encrypted at rest and decrypted only inside the
platform's request path. They never round-trip back through any API —
list / get responses return only an
api_key_prefix(the first few characters) so you can identify which key is which. - A synchronous probe runs at write time. Sonzai does a no-op call to the upstream provider with the key, so bad keys fail PUT with a 400. Misconfiguration surfaces at setup, not on the first user chat.
- Per-key health is tracked. Every read returns
health_status,last_health_error, andlast_health_check_atso you can detect a rotated-out or revoked key before users do — pipe these into a monitor and alert before chat traffic starts failing.
Endpoints
Per project, indexed by (project_id, provider). List all keys, set
one, mark it inactive, delete, or re-test.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/projects/{projectId}/byok-keys | List all keys (redacted) |
PUT | /api/v1/projects/{projectId}/byok-keys/{provider} | Set or rotate the key for a provider (probed before persist) |
PATCH | /api/v1/projects/{projectId}/byok-keys/{provider} | Set is_active true/false without changing the key |
POST | /api/v1/projects/{projectId}/byok-keys/{provider}/test | Re-probe the stored key against the upstream provider |
DELETE | /api/v1/projects/{projectId}/byok-keys/{provider} | Remove the key |
The full request/response shapes are in Reference → API → BYOK.
Scopes for project API keys
Project API keys created via the dashboard or POST /api/v1/projects/{project_id}/api-keys
carry a scopes array. To use BYOK programmatically via the SDK, the key needs:
read:byok— to list providers and check health status.write:byok— to put / disable / delete / re-test keys.
Tenant-level credentials (Clerk dashboard sessions, default API keys with ["*"])
automatically have access to all BYOK operations.
Scope strings are case-sensitive, verb-first, and lower-case (read:byok, not BYOK:Read).
Setting a key
import { Sonzai } from "@sonzai-labs/agents";
const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });
const key = await client.byok.set("project_xyz", "openai", process.env.MY_OPENAI_KEY!);
console.log(key.api_key_prefix); // e.g. "sk-..." — never the full key
console.log(key.health_status); // "healthy" after the synchronous probeListing and inspecting
const keys = await client.byok.list("project_xyz");
for (const k of keys) {
console.log(k.provider, k.api_key_prefix, k.health_status, k.last_used_at);
}Activating, deactivating, deleting
PATCH toggles is_active without rotating the key — handy for
disabling temporarily without losing the key material. DELETE removes
the key and its history.
// Pause this BYOK key (subsequent calls fall back to platform-managed billing)
await client.byok.setActive("project_xyz", "openai", false);
// Re-test
const fresh = await client.byok.test("project_xyz", "openai");
// Permanently remove
await client.byok.delete("project_xyz", "openai");Caching and invalidation
The platform caches the resolved BYOK key per (project_id, provider)
in-process for performance. Every Set / Patch / Delete fires an
invalidator so a rotated key takes effect on the next call without a
restart.
When BYOK doesn't apply
If a project has no BYOK key for the provider that the chat call ends up using, Sonzai bills that provider call to its own platform key as normal — same UX, same SLA. BYOK is purely additive: set a key and it takes over for that provider; remove it and the platform key kicks back in.
Reference
- Custom LLM (BYOM) — entirely your own endpoint, not provider passthrough.
- Providers — the four IDs you can attach BYOK keys to.
- Model scope — how the chat / post-processing model is resolved across project / agent / per-call layers (BYOK applies after that resolution lands on a provider).
- Reference → API → BYOK — REST shape for every endpoint above.