Getting started

Authentication

API keys, live and test modes, scopes and safe rotation.

Every request is authenticated with a secret API key sent as a bearer token. Keys belong to a workspace, carry scopes, and are either live or test.

Sending your key

Pass the key in the Authorization header. Requests without a valid key return 401. All traffic is HTTPS; plain HTTP is refused, not redirected.

curl https://api.intactvoice.com/v1/usage?start=2026-10-01&end=2026-10-05 \
  -H "Authorization: Bearer $API_KEY"

Live and test keys

The prefix tells you the mode at a glance, and the API refuses to mix them (a test key can't read live voices).

PrefixModeBillingBehaviour
sk_live_…LiveUses plan wordsFull models, real voices, counts toward rate limits for your plan.
sk_test_…TestNever billedSame validation and fidelity checks; responses are realistic and deterministic for a given input. Limited to 60 requests/min.

Tip:

Use test keys in CI. Deterministic output means snapshot tests stay stable, and fidelity failures still surface so you can test your error handling.

Scopes

Create restricted keys for each service so a leaked key can do as little as possible.

ScopeGrants
rewritePOST /rewrite, and reading jobs it created.
detectPOST /detect, and reading jobs it created.
voices:readGET /voices/{voice_id}.
voices:writePOST /voices. Implies voices:read.
usage:readGET /usage, for billing dashboards and cost alerts.

A request outside a key's scopes returns 403 permission_denied with the missing scope in error.param.

Rotating keys

Rotate on a schedule (every 90 days is a sensible default) and immediately if a key might have leaked.

  1. Roll the key

    In Dashboard → API keys, choose Roll. You get a new key with the same scopes; the old one keeps working for an overlap window you choose (immediately, 1 hour or 24 hours).

  2. Deploy the new value

    Update your secret manager and redeploy. Nothing else changes: voices, jobs and usage belong to the workspace, not the key.

  3. Confirm traffic has moved

    Call GET /usage with group_by=key. When the old key shows no requests, revoke it.

Warning:

Suspect a leak?

Choose Roll → expire immediately. In-flight async jobs created by the old key still complete and still deliver webhooks.

Keeping keys safe

  • Call the API from your server, a queue worker or an edge function, never from a browser or mobile app.
  • Give each environment and service its own key, so revoking one doesn't take down the rest.
  • Don't log the Authorization header. Request ids (rw_…, dt_…) are safe to log and are what support will ask for.