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).
| Prefix | Mode | Billing | Behaviour |
|---|---|---|---|
sk_live_… | Live | Uses plan words | Full models, real voices, counts toward rate limits for your plan. |
sk_test_… | Test | Never billed | Same 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.
| Scope | Grants |
|---|---|
rewrite | POST /rewrite, and reading jobs it created. |
detect | POST /detect, and reading jobs it created. |
voices:read | GET /voices/{voice_id}. |
voices:write | POST /voices. Implies voices:read. |
usage:read | GET /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.
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).
Deploy the new value
Update your secret manager and redeploy. Nothing else changes: voices, jobs and usage belong to the workspace, not the key.
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
Authorizationheader. Request ids (rw_…,dt_…) are safe to log and are what support will ask for.