Skip to main content
The External API is a REST API over HTTPS that runs a CallVA project: calls and their transcripts and recordings, outbound dispatch, voice agents and their presets and tools, custom fields, assets, knowledge, webhook schedules and logs, automations, variables, projects and phone numbers. Requests and responses are JSON.

Base URL

Every path in this reference is relative to it: GET /calls is https://api.callva.io/api/v1/external/calls. The examples read it from a variable:

Authentication

Send an API token as a bearer token on every request: Authorization: Bearer <token>. Tokens are created in the dashboard under Settings, API Keys; each carries a role that decides which endpoints it may call, and is either bound to one project or reaches every project of the organization. Authentication and permissions covers both in full. Each endpoint page opens with the permission it requires - “Requires permission: calls.read” - and the OpenAPI specification carries the same as the operation’s x-permission field. A token whose role lacks it is answered 403.

Try it in the playground

Every endpoint page has a playground that sends a real request.
  1. Choose Try it on the endpoint’s page.
  2. Paste your API token into the Authorization field. The playground sends it as Bearer <token>.
  3. With an organization-wide token, fill in X-Project-ID with the project to act in. A project token needs nothing more.
  4. Fill in the parameters and send.
The request goes from your browser straight to the CallVA API - not through the documentation site - and it is a real request against your data: a POST, PUT or DELETE changes or deletes real records. The server menu chooses which CallVA API the request goes to; keep it on the production URL above unless CallVA has given you access to another. What you can call is what your token’s role allows; anything else answers 403.
For exploring, create a project token with a read-only role such as Analyst. Nothing you try in the playground can then change your data.

Choosing the project

Almost every request acts in exactly one project.
  • A project token always acts in its own project. A project named in the request is ignored.
  • An organization-wide token names the project in the X-Project-ID header, or as project_id - in the JSON body for writes, in the query string for reads and deletes. A request that names none answers 400 with "code": "PROJECT_REQUIRED"; this includes GET /projects.

Responses

Every response is a JSON envelope. A success carries data:
A failure has success: false, a human-readable message, a machine-readable code where one exists, and errors keyed by field when the input was invalid:
422 Unprocessable Entity
Branch on the HTTP status and on code; the wording of message may change. Identifiers are UUIDs. Dates and times are ISO 8601 in UTC, such as 2026-11-10T21:12:40.000000Z. A call record carries its identity and then every field of the project’s data model at the top level, by field key - see Custom fields.

Pagination

Paginated lists take page (from 1) and per_page, and add a pagination object beside data:
from and to are the positions of the first and last item on the page, and are null on an empty page. Page sizes are capped per list - projects at 100, calls at 1,000 - and the call list also accepts per_page=all to answer every matching call on one page. Walk the pages until current_page equals last_page. The call list filters on any field by its key (status=complete), with operator suffixes such as _gte, _lte, _like and _in (started_at_gte=2026-11-01), sorts with sort (sort=-created_at for newest first), and searches with search. The Calls guide covers them.

Errors

Some endpoints add their own refusals, described on their pages - Place an outbound call, for example, names the reason a call cannot be placed in errors.error.

Limits

The External API sets no per-token request rate limit of its own. What is bounded:
  • Page size, per list, as above.
  • Concurrent calls. Each organization has a limit on calls in progress at once. An outbound call over it is refused with 422 and errors.error set to concurrency_limit_exceeded; place it again once a call ends.

Guides

Quickstart

Create a token and read your first call.

Authentication and permissions

Tokens, roles, project scope and refusals.

Calls

Outbound dispatch, call records, transcripts and recordings.

Custom fields

The data model behind every call.

Webhooks

Scheduled webhooks and webhook logs.

Automations

Scripts that run against your calls.

MCP

Connect an AI agent instead of writing code.

CLI

The callva command line.