OdyDocs

Authentication

Create, use, rotate and revoke Ody API keys. Every request sends Authorization: Bearer ody_live_… or ody_test_….

Ody authenticates every REST and MCP request with an API key sent as a Bearer token. There is no OAuth flow today: keys are created by a workspace admin and belong to that workspace.

Shell
curl https://api.ody.co/v1/api/contacts \
  -H "Authorization: Bearer ody_live_…"

#Key format

PrefixModeBehaviour
ody_live_LiveEverything is real: texts are sent, numbers are bought, calls are dialed
ody_test_TestReads and writes real workspace data, but anything that spends money or reaches the outside world is simulated — see Test mode

After the prefix comes 24 random bytes (base64url). Keys are opaque: don't parse them beyond the prefix.

#Create a key

Only workspace admins and owners can create keys.

  1. In the app, open Settings → Developer API (on a phone: More → Settings → Developer API).
  2. Enter a name — "Production server", "Zapier", "Claude" — so you can tell keys apart later.
  3. Choose its scopes. All are pre-selected (full access); deselect to narrow the key.
  4. Choose Live or Test.
  5. Click Create key and copy the secret from the banner: "Copy your new key now — you won't see it again."

Ody stores only a SHA-256 hash of the key. The plaintext is shown once and can never be retrieved — if you lose it, revoke it and create a new one. The key list shows a masked hint (ody_live_…WXYZ), a Test badge for test keys, the scopes, and when the key was last used.

#What a key can do

A key acts as the member who created it. Every call is checked against that member's role and the workspace's row-level security, exactly as if they clicked the same button in the app. A key can never reach another workspace.

#Errors

StatusCodeMeaning
401unauthenticatedMissing, malformed, unknown or revoked key. Don't retry — fix the configuration
403permission_deniedThe key is valid but lacks the scope this endpoint needs. The message names the scope
JSON
{ "error": { "code": "permission_denied", "message": "This API key is missing the 'messages:send' scope", "requestId": "req_8c1f…" } }

#Rotate and revoke

Revoking is immediate: the next request with that key gets 401. Because a key's plaintext is shown only once, rotation is:

  1. Create a new key with the same scopes.
  2. Deploy it to your service.
  3. Revoke the old key in Settings → Developer API.

#Keep keys safe

Server-side only

Anyone holding a key can act as its creator within its scopes. Never put a key in browser JavaScript, a mobile app, a public repository or a shared document.

  • Store keys in a secrets manager or environment variable.
  • Use one key per integration so you can revoke one without breaking the others, and so "last used" stays meaningful.
  • Give each key the fewest scopes it needs — a reporting dashboard needs only conversations:read.
  • Use test keys in development and CI.

#CORS

/v1/api and /v1/mcp accept requests from any origin, because they authenticate with a bearer key rather than cookies. That makes browser-based tools possible — it does not make it safe to ship a key to end users' browsers.

Last updated Wed Oct 14 2026 00:00:00 GMT+0000 (Coordinated Universal Time)Something wrong on this page? Tell us