/v1 carries a key:
Creating one
Dashboard → API keys → Create key. The secret appears once, at creation. We store an HMAC of it rather than the key itself, so there is no endpoint that can show it to you again and no support request that can recover it. A lost key is replaced, not retrieved. You can also create keys from the API, with a key that holdsapi_keys:write,
but the first key has to come from the dashboard, because there is nothing to
authenticate the request with yet.
Scopes
Keys are scoped, and there is no wildcard.agents:write does not imply
agents:read; grant both if you need both.
The quickstart needs
sip_trunks:write, phone_numbers:write, agents:read,
agents:write, calls:read, calls:write, usage:read and billing:read,
which is exactly what the dashboard preselects.
There is no admin scope
One cannot be created either. Everything an administrator can do is unreachable from an API key by construction, not by a permission check that could be misconfigured: the credential is stripped before it reaches those routes.A key cannot grant what it does not hold
Creating a key with scopes the calling key lacks returns403 scope_escalation.
Otherwise a narrow key would be a step toward a broad one rather than a limit.
Rotation
Revocation
Keys held by AI clients
When claude.ai, Claude Desktop or Claude Code connects through the MCP server with OAuth, the client receives a key of its own with exactly the scopes you approved. Those keys do not appear in the list above or on the API keys page; they are listed, and revoked, under AI clients in the console, so one credential never has two views that can disagree.Storing them
Treat a key like a password. Environment variables or a secret manager; never a repository, a client-side bundle, or a URL. Keys carry awv_live_ or
wv_test_ prefix so a secret scanner can spot one, and so a test key pasted
into production fails loudly instead of quietly operating on real data.
