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.
| Credential | Prefix | Grants | Created by |
|---|---|---|---|
| Channel ingest token | vk_ | Send calls into one channel. Write-only. | Admin, per channel |
| Workspace API key | vlk_ | Read conversations, analytics and channels of one workspace. Read-only. | Admin, per workspace |
| Embed token | ve_ | Render a read-only dashboard of one workspace in an iframe. | Admin, per workspace |
| Share token | vs_ | 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:
/api/workspaces/{workspaceId}/channels/{channelId}/tokensBody { "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}/channelsand 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.
/api/workspaces/{workspaceId}/api-keysDashboard 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
| Status | Meaning |
|---|---|
400 | Malformed request. Body is { "error": "…" } with a human-readable message. |
401 | Missing, invalid, expired or IP-restricted credential. |
402 | The account's monthly minute allowance is exhausted (usage_limit_reached). |
403 | Valid credential, forbidden action (for example a write with an API key). |
404 | Unknown resource, or a resource in a workspace the credential cannot see. |
409 | Conflict, for example a Twilio callback on a channel not configured for Twilio. |
429 | Rate limit exceeded. |
502 | VoiceLens 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.