> ## Documentation Index
> Fetch the complete documentation index at: https://docs.callva.io/llms.txt
> Use this file to discover all available pages before exploring further.

# API reference

> Base URL, authentication, the playground, project selection, the response envelope, pagination and errors of the CallVA External API.

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

```text theme={null}
https://api.callva.io/api/v1/external
```

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:

```bash theme={null}
export CALLVA_API="https://api.callva.io/api/v1/external"
export CALLVA_TOKEN="<your API token>"
```

## 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](https://docs.callva.io/authentication.md) 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`.

> [!TIP]
>
> 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`.

```bash theme={null}
curl "$CALLVA_API/calls?per_page=5" \
  -H "Authorization: Bearer $CALLVA_TOKEN" \
  -H "X-Project-ID: $CALLVA_PROJECT" \
  -H "Accept: application/json"
```

## Responses

Every response is a JSON envelope. A success carries `data`:

```json theme={null}
{
  "success": true,
  "message": "Call retrieved successfully",
  "data": { "id": "01a1c74f-20eb-70d8-ba3f-63afe58bcd8c", "status": "complete", ... }
}
```

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:

```json 422 Unprocessable Entity theme={null}
{
  "success": false,
  "message": "Validation failed",
  "errors": { "name": ["The name field is required."] }
}
```

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](https://docs.callva.io/guides/custom-fields.md).

## Pagination

Paginated lists take `page` (from 1) and `per_page`, and add a `pagination` object beside `data`:

```json theme={null}
"pagination": { "current_page": 1, "last_page": 1, "per_page": 5, "total": 4, "from": 1, "to": 4 }
```

`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](https://docs.callva.io/guides/calls.md) covers them.

## Errors

| Status | `code` | Meaning |
| - | - | - |
| `400` | `PROJECT_REQUIRED` | An organization-wide token named no project. |
| `401` | - | The token is missing, unknown or deleted. This answer is `{"error": "...", "message": "..."}`, with no `success` field. |
| `403` | `insufficient_permission` | The token's role does not hold the permission the endpoint requires. |
| `404` | `PROJECT_INVALID` | The named project does not exist, belongs to another organization, or is inactive. |
| `404` | `RESOURCE_NOT_IN_PROJECT`, or none | The record in the path does not exist in the request's project. |
| `422` | - | The input failed validation; `errors` says which field and why. |
| `500` | - | CallVA failed to complete the request. Retry later; if it persists, contact support with the time and the endpoint. |

Some endpoints add their own refusals, described on their pages - [Place an outbound call](https://docs.callva.io/api-reference/outbound-calls/place-an-outbound-call.md), 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

> [card] [Quickstart](https://docs.callva.io/quickstart.md)
>
> Create a token and read your first call.

> [card] [Authentication and permissions](https://docs.callva.io/authentication.md)
>
> Tokens, roles, project scope and refusals.

> [card] [Calls](https://docs.callva.io/guides/calls.md)
>
> Outbound dispatch, call records, transcripts and recordings.

> [card] [Custom fields](https://docs.callva.io/guides/custom-fields.md)
>
> The data model behind every call.

> [card] [Webhooks](https://docs.callva.io/guides/webhooks.md)
>
> Scheduled webhooks and webhook logs.

> [card] [Automations](https://docs.callva.io/guides/automations.md)
>
> Scripts that run against your calls.

> [card] [MCP](https://docs.callva.io/mcp.md)
>
> Connect an AI agent instead of writing code.

> [card] [CLI](https://docs.callva.io/cli.md)
>
> The `callva` command line.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.