Platform
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:
{
"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:
{
"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:
| Scope | What it opens |
|---|---|
project:read | reserved; no /v2 route enforces it today |
voice:read | list and read agents and voice sessions |
voice:write | create, update and delete agents; start sessions |
provider_account:read | list and read provider accounts |
provider_account:write | save, probe, rotate and disconnect them |
carrier:read | carrier catalogue, connections and numbers |
carrier:write | connect, verify, disconnect; import, attach, update and delete numbers |
webhook:read | list endpoints and dead letters |
webhook:write | create, 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.