Skip to main content
The Callers REST API lets you run your agents from your own systems: add contacts, start and stop agents, read calls and recordings, manage voices, and configure subaccounts. Everything you can automate from the dashboard’s day-to-day workflow is available here, and webhooks push call results back to you as they happen. This page covers the conventions every endpoint shares. To make your first calls, follow the API quickstart.

Base URL

All requests go to:
All traffic is HTTPS. Request and response bodies are JSON unless an endpoint says otherwise (voice cloning and background sound uploads use multipart/form-data). JSON request bodies can be up to 1 MB.
White-label accounts with a custom domain can also call the API at https://<your-domain>/api. See White label.

Authentication

Every request needs an API key in the Authorization header. Send the key as-is: no Bearer prefix.
Create and revoke keys in the dashboard under Settings → API Keys. See API keys for the steps and the member permission needed to manage keys. A key belongs to one account and can read and change everything in that account. Keep keys on your server: never ship them in browser or mobile code, and rotate a key if it leaks. For calls started from a web page, the browser never sends your API key: the Web SDK uses short-lived signed tokens and the public GET /agents/{agentId}/web-call/config endpoint. See Authentication and Bot protection.
GET /agents/{agentId}/web-call/config needs no API key and isn’t listed in the OpenAPI spec. It’s used by the Web SDK and returns only the public settings a browser needs to start a call (for example the Turnstile site key). See Bot protection.
A missing, invalid, or revoked key returns 403 Forbidden (not 401), with the body {"status": "error", "message": "Forbidden resource"}.

Acting on a subaccount

If you manage subaccounts, you can use your main account’s key to act on any of them. Add the subaccount’s ID in the x-sub-organization-id header:
The request then runs exactly as if it were made with a key from that subaccount.
  • If the header is omitted, or equals your own account ID, the request runs on your main account.
  • If the ID is not a subaccount of the key’s account, the request is rejected with 403 Forbidden resource. The API does not fall back to the main account.
  • Subaccount IDs are returned by GET /organization (your account first, then its subaccounts) and by POST /organization/sub-organization.
See Subaccounts and SIP for the full workflow.

Response format

Successful responses wrap the result in an envelope:
data holds the object, array, or value the endpoint returns. Some actions (for example, starting an agent) return no data.

Errors

Errors use the same envelope with status: "error", a human-readable message, and, for validation errors, a data array describing each problem:
Treat 429, 500, and 503 as retryable, and use exponential backoff. Don’t retry 400, 403, or 404 without changing the request.

Pagination

List endpoints that can return many items accept two query parameters:
Most list endpoints return a plain array in data. Keep requesting the next page until you get fewer items than perPage. GET /agents/{agentId}/contacts/{contactId}/calls returns { data, total, page, perPage } inside the envelope.

IDs and naming

  • IDs are 24-character hexadecimal strings (for example, 6650c1f2a1b2c3d4e5f60718). Malformed IDs return 400.
  • Agents vs. campaigns. Agents were called campaigns in earlier versions of Callers. Use the /agents paths (/agents/{agentId}, /agent-groups/{agentGroupId}). The legacy /campaigns and /campaign-groups paths still work and behave identically, so existing integrations keep running.
  • Some fields keep the legacy name. Responses include both campaignId and agentId where relevant, and the webhook payload describes the agent in a campaign object (campaign.id, campaign.name).
  • Organization in the API means your Callers account. A sub organization is a subaccount.

Phone numbers

Send phone numbers in international format with the country code, preferably E.164 (+14155552671). The API accepts 7–20 characters made of digits, (, ), -, and an optional leading +, and stores the number as digits only (14155552671). Responses return numbers in that normalized form.
  • Numbers are validated as international numbers. Invalid numbers are rejected (single contact) or skipped (bulk).
  • fixUSPhoneNumber=true adds a leading 1 to 10-digit numbers. Use it when your source data has US numbers without the country code.
  • Agents that use local dialing skip the international format check. See Phone numbers and caller ID.

Duplicate contacts and safe retries

Adding contacts is idempotent per agent and phone number. When you add a contact whose primary phone number already exists in that agent, Callers updates the existing contact (name, data, phone numbers, time zone) instead of creating a second one. Its status and attempt history are kept. The response tells you which happened: created/modified for a single contact, added/modified counts (and per-contact created/updated with verbose=true) for bulk. This means you can safely retry a contact upload after a timeout. The exception is agents with Allow Duplicate Phone Numbers turned on: every upload creates new contacts, so don’t blindly retry those requests. There are no idempotency keys for other write endpoints. Before retrying a request that creates something, such as a voice or subaccount, check whether the first attempt succeeded.

Rate limits

The API doesn’t publish a fixed request quota. Keep concurrency reasonable: send contacts in bulk requests instead of one request per contact, avoid tight polling loops (use webhooks to learn about call results), and back off when you receive 429 or 5xx responses. If you plan to load very large contact volumes or run many agents in parallel, email first so we can make sure your account is set up for it. A minimal retry with exponential backoff in Node.js:
Only retry requests that are safe to repeat (reads, and contact uploads, which update existing contacts rather than duplicating them). Don’t retry 400, 403, or 404.

Versioning and changes

The API is unversioned: there is one current version at https://api.callers.ai. We add new endpoints and new fields to responses without notice, so ignore unknown fields in responses and webhook payloads instead of failing on them. Breaking changes are announced in advance, and renamed resources keep working under their old names (as with /campaigns). The OpenAPI spec is always up to date at https://api.callers.ai/openapi-json. Product changes are listed in the changelog.

Next steps

API quickstart

Add contacts, start an agent, and receive your first webhook.

Launch outbound calls

Run an outbound agent end to end from your system.

Manage contacts

Add, update, filter, and archive contacts.

Manage agents

Create, update, duplicate, and delete agents.

Webhooks

Get call results pushed to your endpoint.

Subaccounts and SIP

Manage subaccounts, SIP carriers, and numbers.