API key format
OptimalDial keys look like this:- The prefix
od_live_identifies the environment (currently onlyliveexists). - The remainder is 32 URL-safe characters of cryptographic randomness (256 bits of entropy).
- Total length is around 40 characters.
- Keys are case-sensitive.
od_live_FxXk) so you can identify which key you’re holding without revealing the secret.
If you lose a key you must create a new one — there is no “show key” recovery. Treat the secret like a password.
Creating an API key
- Sign in at app.optimaldial.com as an organization owner.
- Open Developers in the sidebar (admin-gated during pre-release).
- Click Create API key, give it a descriptive name (e.g.
production-billing-pipeline), and optionally set anexpires_atdate. - Copy the full key from the one-time reveal panel and store it in your secrets manager before closing the modal.
Sending the key on requests
Pass the key in theAuthorization header as a Bearer token. This is the only thing that needs to change between an unauthenticated request and an authenticated one.
- cURL
- Node.js
- Python
X-Organization-Id on public-API requests — the key already binds the call to the organization that minted it.
What a key gives access to
Each key is scoped to one organization and carries a static set of permissions:| Scope | Lets the key… |
|---|---|
uploads:write | Create and cancel uploads |
uploads:read | List uploads, fetch upload details, generate download URLs |
webhooks:manage | Create, update, delete webhook endpoints; list deliveries |
Rotating keys
Keys never expire automatically unless you set anexpires_at value at creation. To rotate:
- Create a new key in the developer panel.
- Deploy the new key to your application (env var or secret manager).
- Verify with a single request that the new key works.
- Revoke the old key in the developer panel.
Auto-revocation when a user leaves an organization
If the user who minted a key is removed from the organization (or removes themselves), every key they created for that organization is auto-revoked at the database level. This is enforced by a trigger, not by application code, so it survives bugs and outages. Practical consequence: keys should be minted by a long-lived owner account (e.g. a service-owner identity), not by an individual employee who might leave.Authentication errors
A failed auth attempt always returns401 Unauthorized with WWW-Authenticate: Bearer and one of:
| Body | Reason |
|---|---|
{"detail":"API key required"} | Missing or empty Authorization header |
{"detail":"Invalid API key format"} | Header is present but doesn’t start with od_live_ |
{"detail":"Invalid or revoked API key"} | Key was revoked, expired, or doesn’t exist |
{"detail":"API key creator no longer exists"} | The minting user was deleted |
{"detail":"Organization for this API key no longer exists"} | The organization was deleted |
403 Forbidden is reserved for subscription failures, not auth — see errors and rate limits.