Campaign stats
Fetch a snapshot of contact and attempt counts for a campaign.campaigns:read or campaigns:manage scope. The X-Anyreach-Org header is only needed for user PATs (pat_); org API keys (ak_) carry their org implicitly.
The response groups contacts by lifecycle bucket and reports attempt totals plus current concurrency:
Response fields
| Field | Type | Description |
|---|---|---|
campaign_id | string | The campaign this snapshot belongs to. |
status | string | Current campaign status (for example active). |
contacts.total | integer | Sum of all contacts across buckets. |
contacts.pending | integer | Contacts not yet attempted. |
contacts.in_progress | integer | Contacts currently being dialed (includes locked and in-progress contacts). |
contacts.completed | integer | Contacts that reached a terminal completed state. |
contacts.exhausted | integer | Contacts that ran out of retry attempts. |
attempts.total | integer | Total call attempts made across all contacts. |
attempts.average_per_contact | number | attempts.total divided by contacts.total, rounded to two decimals. 0.0 when there are no contacts or attempts. |
active_calls | integer | Calls in flight at the moment of the request. |
concurrency_limit | integer | The org-level cap on simultaneous calls. Defaults to 10 when no org setting exists. |
active_calls and concurrency_limit together tell you how much headroom the campaign has. When active_calls reaches concurrency_limit, the dialer waits for a call to finish before starting the next one. See Dialing and retries.Live polling
The campaign Overview tab calls the stats endpoint on load and then polls it every 5 seconds while the campaignstatus is active and the browser tab is visible. Polling stops when the tab is hidden or the campaign is no longer active, and resumes when the tab becomes visible again. Use the refresh control to fetch on demand at any time.
Attempts and conversations
Each call attempt links to a conversation through itsconversation_id. List a campaign’s contacts to see their attempts:
limit defaults to 50 (max 200) and offset defaults to 0. Pass status to filter contacts by bucket. Each contact carries an attempts array, and every attempt includes:
| Field | Type | Description |
|---|---|---|
id | string | Attempt identifier. |
contact_id | string | The contact this attempt belongs to. |
phone_number | string | The number dialed for this attempt. |
conversation_id | string | null | The linked conversation, or null if no conversation was created. |
started_at | datetime | When the attempt started. |
ended_at | datetime | null | When the attempt ended, if finished. |
status | string | The attempt’s status. |
result | object | null | Per-conversation evaluation outcomes (see below). |
Conversation outcomes
When an attempt produced a conversation, the contacts list enriches that attempt with its evaluation outcome. For each attempt with aconversation_id, the server looks up completed evaluation runs for that conversation and populates the attempt’s result object, keyed by <metric_key>.<criterion_key>. Attempts whose conversation has no completed evaluation, or no conversation at all, leave result as null.
To review the full transcript and recording for any attempt, open the linked conversation by its conversation_id in Conversations.
Conversations
Read transcripts and listen to recordings for every linked conversation.
Dialing and retries
Understand how attempts, retries, and concurrency drive the stats buckets.

