Authentication

The three credential types VoiceLens exposes to integrations: channel ingest tokens for sending calls, workspace API keys for reading data, and embed and share tokens for public surfaces.

The VoiceLens API lives under https://voicelens.app/api. All responses are JSON with camelCase property names; timestamps are ISO 8601 in UTC. Integrations use one of three credential types depending on what they do.

CredentialPrefixGrantsCreated by
Channel ingest tokenvk_Send calls into one channel. Write-only.Admin, per channel
Workspace API keyvlk_Read conversations, analytics and channels of one workspace. Read-only.Admin, per workspace
Embed tokenve_Render a read-only dashboard of one workspace in an iframe.Admin, per workspace
Share tokenvs_Open one call's scorecard.Member, per call

Dashboard sessions use short-lived JWTs and are not intended for integrations.

Channel ingest tokens

Ingest tokens authenticate the ingest endpoints only. They are bound to a single channel; a request whose URL names a different channel is rejected.

Send the token in either header:

X-Ingest-Token: vk_live_3f9c…
Authorization: Bearer vk_live_3f9c…

Tokens can carry an optional expiry and an IP allowlist (CIDR ranges). Requests from other addresses receive 401. Each use updates the token's last-used time, IP and usage counter, which you can see on the channel page. There is no dedicated rate limit on ingest.

Create tokens under Channels, or through the dashboard API:

POST/api/workspaces/{workspaceId}/channels/{channelId}/tokens

Body { "name", "allowedIpRanges"?, "expiresAtUtc"? }. The response contains the token record and the plaintext, which is never shown again. GET the same path to list tokens and DELETE …/tokens/{tokenId} to revoke one.

Workspace API keys

API keys give read-only access to one workspace as a Viewer. Send them in either header:

X-Api-Key: vlk_9d1e…
Authorization: Bearer vlk_9d1e…

Allowed endpoints (GET and HEAD only):

  • /api/conversations, /api/conversations/search, /api/conversations/{id} (not the audio endpoint)
  • /api/analytics/*
  • /api/workspaces/{workspaceId}/channels and channel details (not the token endpoints)

Any other method or path returns 403 with { "error": "…", "code": "api_key_read_only" }.

Limits: up to 20 active keys per workspace, optional expiry, revocation from Workspace settings, API keys, and a rate limit of 600 requests per minute per key. Exceeding it returns 429.

POST/api/workspaces/{workspaceId}/api-keys

Dashboard session required (Admin). Body { "name", "expiresAtUtc"? }. Returns the key record and its plaintext once. DELETE …/api-keys/{keyId} revokes.

Embed and share tokens

Embed tokens (ve_) are consumed by embed.js and the public embed endpoints under /api/embed/*; they are sent as X-Embed-Token and rate-limited to 240 requests per minute. Share tokens (vs_) are consumed by the share page through /api/share with X-Share-Token, rate-limited to 60 per minute per IP. Neither is meant to be called from your own code; see Embedded dashboards and Shareable scorecards.

Errors

StatusMeaning
400Malformed request. Body is { "error": "…" } with a human-readable message.
401Missing, invalid, expired or IP-restricted credential.
402The account's monthly minute allowance is exhausted (usage_limit_reached).
403Valid credential, forbidden action (for example a write with an API key).
404Unknown resource, or a resource in a workspace the credential cannot see.
409Conflict, for example a Twilio callback on a channel not configured for Twilio.
429Rate limit exceeded.
502VoiceLens could not fetch a remote resource you pointed it at (from-URL ingest, Twilio download).

Good practice

  • Store tokens in a secret manager and inject them at runtime; never commit them.
  • Use one ingest token per integration and one API key per consuming system, named after that system, so revocation is surgical.
  • Set an IP allowlist on ingest tokens used from fixed infrastructure.
  • Rotate by creating the new credential first, switching, then revoking the old one.