Authentication
Orbit authenticates API requests two ways: an API key for server-to-server calls, and a session Bearer token for dashboard users. Enterprise organizations can additionally sign users in through SAML single sign-on and provision them through SCIM. Pick the method that matches how the request is made.API Key (Server-to-Server)
Include your API key in theX-API-Key header:
- Node.js
- Python
- Go
ORBIT_API_KEY on your server, never in client-side code. Full install
and usage for every language is under SDKs.
Bearer Token (Dashboard Users)
For dashboard users, use JWT Bearer tokens:You may also pass an API key via
Authorization: Bearer dv_live_pk_... (any
dv_ key — dv_live_sk_, dv_test_sk_, dv_live_pk_, dv_test_pk_) for
environments where the X-API-Key custom header is blocked by CORS. The server
accepts either form: it reads X-API-Key first, then falls back to a Bearer
token that carries a dv_ prefix. A JWT (which starts with eyJ) is still
treated as a dashboard session token, so the two never collide.API Key Format
Create your first key in the dashboard
The Settings → API Keys page in the dashboard is the same key surface the create endpoint above drives. Click Create key and set three things:- Type — the same four classes as the format table: live secret
(
dv_live_sk_), test secret (dv_test_sk_), live public (dv_live_pk_), or test public (dv_test_pk_). Pick a test secret for a first integration: it can never deliver real traffic or bill your wallet, so your first run is free of side effects. - Scopes — grant the minimum the integration needs. Public keys accept read-only scopes only; write and administrative scopes are rejected at creation, as the example above shows.
- Expiry — optionally give the key an
expires_at. A key with no expiry stays valid until you rotate or revoke it; a short expiry suits trials and CI runners.
POST /api/v1/settings/api-keys call above creates the same key with
type and scopes in the body.
For a full first-key-to-production recipe — sandbox key first, then a scoped
production key, then the controls below — follow the
API keys end-to-end guide.
Manage the key after creation
Minting the key is step one. Orbit then gives each key a lifecycle and a set of per-key controls, all reachable from the same Settings → API Keys surface and thesettings/api-keys API.
Rotate on a schedule, not on a rumor. Rotation
(POST /api/v1/settings/api-keys/:id/rotate) mints a replacement and retires
the old key in one of two modes:
- Grace (default). The old key stays valid for
grace_period_hours(default 24, clamped to 1–168 hours) so both keys authenticate while you migrate. The response’sold_key_expires_attells you the exact cutoff — it is the earlier of the old key’s originalexpires_atand the end of the grace window. - Immediate. The old key is revoked in the same transaction. Reserve this for a leaked key; routine rotations should always overlap.
- Usage limits — a requests-per-minute rate
limit and a monthly request quota per key (or as an org-wide default), so a
noisy or compromised key trips its own
429instead of consuming the throughput your other keys share. - Usage budget alerts — a lightweight per-operator threshold on a key’s analytics drawer that badges the key as usage crosses 80% and 100% of the ceiling.
- Spend budgets — a persisted monthly money ceiling per key (minor currency units plus ISO-4217 currency) with one alert per threshold, shared with your whole team.
What to do when a key leaks
A key committed to a repo, pasted into a chat, or found in someone else’s logs is an incident, not a hygiene task. Act in this order:- Revoke first. Send
POST /api/v1/settings/api-keys/:id/revokebefore anything else. Revoking a leaked key stops the meter at the revoke timestamp — usage billed into your account ends there regardless of what the leaked key does afterward — so revocation is always the right first move, even before you investigate. - Mint a replacement. If the integration must keep working, rotate with
mode: "immediate"instead of a bare revoke: the replacement is minted and the old key is killed in one transaction. Copy the new plaintext from the rotation response — it is the only place it ever appears. - Review the damage path. Check the key’s usage in its analytics drawer
(usage limits) and its audit log entries —
grace rotations write
api_key.rotated, panic-revokes writeapi_key.revoked_immediate, so a compliance review can tell them apart. - Prevent the repeat. Scope the replacement minimally, add an IP allowlist so the key only works from your network, and consider an expiry so forgetful cleanup stops being a risk.
Troubleshooting
Most authentication failures resolve in seconds once the rejection code is decoded —INVALID_API_KEY, EXPIRED_TOKEN, WRONG_KEY_MODE, and the
distinguishing messages all map to a specific gate. See
Troubleshooting: authentication, key mode, and IP allowlist failures.
For rate and quota rejections (429), see
Troubleshooting: rate limits. Dashboard
login lockouts (ACCOUNT_LOCKED on users, not API keys) are covered in
Troubleshooting: ACCOUNT_LOCKED at dashboard sign-in.
Single sign-on (SAML)
Enterprise organizations can log dashboard users in through a SAML 2.0 identity provider — Okta, Microsoft Entra ID (formerly Azure AD), OneLogin, Google Workspace, or PingFederate. SSO authenticates people into the dashboard; it does not mint API keys, so server-to-server calls still use the methods above. An owner configures the connection under Settings → Single sign-on in the dashboard (or viaPATCH /api/v1/settings/saml): set your IdP’s SSO URL, entity
ID, and signing certificate, then use Test connection before enabling it.
Each organization gets its own set of endpoints, keyed by your organization slug
(orgSlug). They live at the API root, not under /api/v1:
Point your IdP at the metadata endpoint, for example
https://api.orbit.devotel.io/auth/saml/acme/metadata for the acme
organization. The response — served as application/xml — is the
service-provider descriptor your IdP admin imports:
NameIDFormat, no secrets.
Directory provisioning (SCIM)
Provision and deprovision dashboard users automatically from your identity provider over SCIM 2.0. Generate a provisioning token under Settings → SCIM (or viaPOST /api/v1/settings/scim/generate-token) — the token is shown once,
so copy it into your IdP immediately.
Your IdP sends the token as a Bearer credential on every request:
application/scim+json. They are
keyed by your organization slug and live at the API root, not under
/api/v1:
A worked user create — the exact shape your IdP (or a direct client) sends and
gets back for
POST /scim/v2/{orgSlug}/Users:
201 response is the created User resource, application/scim+json:
SAML and SCIM are independent: SSO controls how users sign in, SCIM controls
which users exist. You can enable either on its own, though most IdPs configure
both together.