Base URL
/v1 path prefix — we add new fields additively and
avoid breaking changes within v1.
API keys
Create a key from the dashboard:1
Sign in
Log into the ThunderPhone Dashboard.
2
Open Keys
Navigate to Settings → Keys.
3
Create key
Click Create API Key, give it a name (e.g.
production, ci), and copy the sk_live_... value.
The raw key is shown only once — if you lose it, revoke and create a new one.API keys are exempt from the “Require passkeys” org policy. Passkeys
are a human 2FA check performed at sign-in and on session use; an
sk_live_... key is a machine credential with no login session to
attach a passkey check to, so it authenticates independently of that
policy even when it’s enabled for your organization. This is intentional
— treat key issuance and rotation as your access control for
server-to-server integrations, and audit or revoke keys from
Organization → Keys the same way you would rotate any other
standing credential. See Create a server API key
and Enterprise SSO for how the policy
applies to human members.Making a request
Send the key as a bearer token in theAuthorization header. The API
infers your organization from the key, so you don’t need an org id in
the URL path.
Successful JSON responses use
200 OK for reads and 201 Created for
writes. Deletes return 204 No Content. Errors use the standard HTTP
status codes listed below.Health check
Verify API connectivity without authentication:Response
Dashboard access (X-ThunderPhone-Org)
The dashboard at app.thunderphone.com authenticates users with a personal session/token (one user can belong to many organizations). Those requests identify the target organization via theX-ThunderPhone-Org header:
sk_live_ key should omit
it; the key already carries an org binding and the header, if present, is
ignored for API-key requests.
ID format
Most core resources use 64-bit integer ids (agents, phone numbers, calls, members, organizations, publishable keys, VoIP connections). Newer resources use UUID ids — integrations, developer API keys, webhook endpoints, campaigns, knowledge bases and documents, MCP servers, provider connections, investigations, and test suites — and issue reports are addressed by a UUIDtrace_id. Each page states the
id type in its object table. Tokens (invites, API keys) are opaque
strings. Every successful write returns the persisted object including
its assigned id:
Pagination
List endpoints return a plain JSON array by default. Endpoints that can produce very large result sets (currently calls and issue reports) acceptlimit and offset query parameters and
return a wrapped envelope:
limit to the current offset on each request
and stop when offset + limit >= total. See each endpoint’s page for
the default and maximum limit it accepts.
Billing transactions also
accept
limit/offset but return a plain array without the envelope
— page forward until you receive fewer rows than limit.Errors
The API uses conventional HTTP status codes:
Error responses include a JSON body with a human-readable
detail
message:
Error body
400) instead map each offending
field to a list of messages, using DRF’s default format:
Validation error
Most endpoints return only
detail (or the field-error map) —
there is no machine-readable code field on generic errors. The
exception is Billing, whose payment
errors add code, retryable, and next_action fields so clients
can drive recovery flows (3-D Secure, card update, retry).Rate limiting
There is no global rate limit on the API today, and general endpoints never return429. A small number of specific endpoints
carry scoped limits — for example, invite access
requests are
limited to 3 per hour per user, and simulations enforce a cap on
concurrently running calls. These are documented on the relevant
endpoint pages and return 429 Too Many Requests when exceeded (no
Retry-After header is sent). Treat write operations as
non-idempotent unless the endpoint documents otherwise.
Migration from /v1/orgs/<id>/... paths
The API previously nested every resource under your organization id in
the URL path — e.g. /v1/orgs/42/agents. Those URLs now return 410 Gone with a body pointing to the new flat shape:
/orgs/<id>
from every URL. Your sk_live_ key is unchanged and continues to
identify your organization automatically.
Next steps
Quickstart
Create your first agent, provision a number, and take a test call.
Agents
Configure voices, prompts, and tool integrations.
Calls
List, inspect, and export call history.
Webhooks
Subscribe to real-time events.