Developer platform · v2

Platform

View as MarkdownAll docs

Projects and keys

Projects#

List projects with GET /v2/projects?limit=25&offset=0 and read one with GET /v2/projects/{project_id}, using an account JWT.

A project response contains id, name, optional external_reference, status, revision, is_default, the voice concurrency, API rate and maximum call-second limits, and timestamps.

Create with POST /v2/projects:

json
{
  "name": "Production",
  "external_reference": "customer_42"
}

The name is required and limited to 120 characters. The reference is optional.

Scoped keys#

Create with POST /v2/api-keys and an account JWT:

json
{
  "name": "Production server",
  "project_id": "00000000-0000-0000-0000-000000000000",
  "scopes": ["project:read", "voice:read", "voice:write"]
}

These nine scopes exist, spelled exactly this way. An unknown scope is refused with 400, so copy them rather than guessing a plural:

ScopeWhat it opens
project:readreserved; no /v2 route enforces it today
voice:readlist and read agents and voice sessions
voice:writecreate, update and delete agents; start sessions
provider_account:readlist and read provider accounts
provider_account:writesave, probe, rotate and disconnect them
carrier:readcarrier catalogue, connections and numbers
carrier:writeconnect, verify, disconnect; import, attach, update and delete numbers
webhook:readlist endpoints and dead letters
webhook:writecreate, test and disable endpoints (it mints a signing secret)

Request only the scopes a server actually needs — a key handed to a partner app to start sessions should not also be able to disconnect the carrier account those sessions run on. The API reference names the scope on every machine operation.

The creation response is { "key": { ...safe metadata }, "plaintext": "..." }. Plaintext appears once. List with GET /v2/api-keys?project_id=...; revoke with DELETE /v2/api-keys/{key_id}.

Use one project per boundary

Provider secrets stay encrypted and project API keys stay on your server.