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:

ScopeReadsWrites
readVoices, usage,
synthesisVoices, usageTTS, STT
adminEverythingTTS, 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:

  1. Generate a new key in the dashboard.
  2. Roll it out to your runtime (Vault, SSM, Doppler, Kubernetes secret, whatever you use) without removing the old key yet.
  3. Confirm traffic is flowing on the new key via the Usage tab (filterable by API key).
  4. 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

  1. Revoke it from the dashboard immediately. Confirm the revoke timestamp on the key's detail page.
  2. Rewrite your git history with git filter-repo (or git filter-branch on older installs) so the key is scrubbed from the public commit graph, then force-push.
  3. Audit Usage → Events for calls authenticated with that key after your last intended use. Anything unexpected is suspicious.
  4. 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.