Base URL
All requests go to: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 theAuthorization header. Send the key as-is: no Bearer prefix.
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.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 thex-sub-organization-id header:
- 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 byPOST /organization/sub-organization.
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 withstatus: "error", a human-readable message, and, for validation errors, a data array describing each problem:
Pagination
List endpoints that can return many items accept two query parameters: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 return400. - Agents vs. campaigns. Agents were called campaigns in earlier versions of Callers. Use the
/agentspaths (/agents/{agentId},/agent-groups/{agentGroupId}). The legacy/campaignsand/campaign-groupspaths still work and behave identically, so existing integrations keep running. - Some fields keep the legacy name. Responses include both
campaignIdandagentIdwhere relevant, and the webhook payload describes the agent in acampaignobject (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=trueadds a leading1to 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 receive429 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:
400, 403, or 404.
Versioning and changes
The API is unversioned: there is one current version athttps://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.