API keys
API keys are the primary credential for the Hakim public API. Every
request authenticates with a Bearer token that maps back to an
organisation, a human owner, and (optionally) a scope.
Creating a key
From the dashboard: Settings → API keys → Create key. Give the key
a descriptive name, it's the only thing separating prod-gateway
from local-dev-lisa-macbook six months later.
We generate the key server-side and show it to you exactly once:
sk_live_hkm_01HNQ9S4ZXN4F7N6M5CY8J6F3P
Copy it into your secret manager immediately. If you lose it, revoke it and create a new one, we never retain the plaintext.
Using a key
Every request sends the key in the Authorization header:
curl https://api.tryhakim.ai/v1/voices \
-H "Authorization: Bearer $HAKIM_API_KEY"
Our SDKs do this for you:
import { HakimClient } from '@hakim/node';
const client = new HakimClient({ apiKey: process.env.HAKIM_API_KEY });
from hakim import HakimClient
client = HakimClient(api_key=os.environ["HAKIM_API_KEY"])
Never put a key in browser bundles, mobile binaries, or public repositories. If you need client-side calls, proxy them through a server route that injects the key.
Key hygiene
One key per environment. A typical setup has at least three:
prod, staging, and a shared local-dev pool. Rotate them
independently.
One key per automation. A CI pipeline, a data-ingest cron, and your production API gateway each deserve their own key. When an automation gets retired, revoke its key, every key you leave behind is a breach radius you're paying to keep.
One key per integration partner. If you embed Hakim on behalf of customers, issue one key per tenant and scope it to their organisation (see scopes below).
Scopes
Every key carries a scope that limits what it can do:
| Scope | Reads | Writes |
|---|---|---|
read | Voices, usage | , |
synthesis | Voices, usage | TTS, STT |
admin | Everything | TTS, STT, jobs, voices, webhooks, ... |
synthesis is the right choice for 90% of integrations, it's the
minimum that lets an app generate audio. Keep admin keys for
dashboards and back-office tooling that actually need to mutate
webhooks or voice-clone state.
Rotation
Rotate keys on a schedule that matches your threat model. For most SaaS deployments, that's every 90 days.
The safe rotation dance:
- Generate a new key in the dashboard.
- Roll it out to your runtime (Vault, SSM, Doppler, Kubernetes secret, whatever you use) without removing the old key yet.
- Confirm traffic is flowing on the new key via the Usage tab (filterable by API key).
- Revoke the old key.
Revoking is instantaneous, every in-flight call authenticated with
the old key will start returning revoked_api_key errors at the
next request.
Accidentally committed a key
- Revoke it from the dashboard immediately. Confirm the revoke timestamp on the key's detail page.
- Rewrite your git history with
git filter-repo(orgit filter-branchon older installs) so the key is scrubbed from the public commit graph, then force-push. - Audit Usage → Events for calls authenticated with that key after your last intended use. Anything unexpected is suspicious.
- File a support ticket if you think the key was exploited, we can correlate IPs and calling patterns against your audit window.
Per-request identity
If you need to attribute a specific call to an end-user (for
audit logging, per-tenant throttling on your side, or just for
traceability in our usage events), send X-Hakim-End-User-Id on each
request. The value is opaque to us; we store it verbatim on the usage
event and surface it in the dashboard Events table.
curl https://api.tryhakim.ai/v1/audio/speech \
-H "Authorization: Bearer $HAKIM_API_KEY" \
-H "X-Hakim-End-User-Id: user_42" \
-d '{"model":"hakim-fast-v1","input":"Hello","voice":"cmokbc2b1001pvu39wmj61b7h"}'
Rate limits and keys
Rate limits are applied per organisation, not per key. Issuing more keys doesn't get you more throughput, it gets you better attribution and revocation granularity. See the rate-limits guide.