Get a campaign's live progress
Everything needed to render a campaign's progress, computed on read.
Everything needed to render a campaign's progress, computed on read.
outcome_counts is the set to render. Its four buckets are mutually
exclusive and always sum to total, and completed is sticky: a
contact that answered on any attempt stays completed even if a later
follow-up fails, so the number only ever goes up.
Three numbers that are routinely misread:
contacts_dialledcounts DISTINCT contacts dialled at least once. It is not the first-attempt call count, which double-counts any contact re-queued with a fresh retry budget — that is how "2,745 dialled" appears on a 2,504-contact list.call_counters.voicemail_callsis a SUBSET ofno_answer_calls, not a peer of it. Adding them together double-counts. It is the "how much of this campaign is hitting an answering machine" dimension, and a high number means the calling window is wrong.retry_breakdowncounts calls per retry depth and EXCLUDES follow-ups, which are reported separately asfollow_up_attempts. Duplicate legs of a call that was already counted are excluded everywhere, so these totals agree with the call list.
Rate limit: 1000 requests per minute per organization (bucket default). Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.
v2/campaigns/{campaign_id}/statsAuthorization
AuthorizationRequiredBearer <token>
Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.
In: header
Path Parameters
campaign_idRequiredCampaign Id
Campaign identifier.
Query Parameters
organization_idOrganization Id
Must match the organisation the API key belongs to.
Response Body
200
Live contact, batch and call numbers for this campaign.
campaign_idRequiredCampaign Id
Campaign identifier.
statusRequiredStatus
The campaign's status at the moment of the read.
timezoneTimezone
IANA timezone the windows are evaluated in.
"UTC"working_hours_enforcedWorking Hours Enforced
Whether dialling is confined to the windows.
falsestart_timeStart Time | null
ISO-8601 UTC.
end_timeEnd Time | null
ISO-8601 UTC.
total_contactsTotal Contacts
Contacts across every batch, counted live.
0contacts_dialledContacts Dialled | null
DISTINCT contacts dialled at least once. Never inferred from the first-attempt call bucket, which double-counts a contact that was re-queued with a fresh retry budget.
in_flight_contactsIn Flight Contacts
Contacts dispatching, ringing or talking now.
0outcome_countsRequiredOutcome Counts
The authoritative progress numbers.
contact_countsContact Counts
Live per-status contact histogram, for drill-downs. Statuses overlap the buckets above.
batch_countsBatch Counts
How many batches sit in each batch status.
call_countersRequiredCall Counters
Stored per-call counters.
retry_breakdownRetry Breakdown | null
Calls placed at each retry depth: '0' is first attempts, '1' the first retry, and so on. Null when the histogram could not be computed for this campaign.
follow_up_attemptsFollow Up Attempts | null
Follow-up calls placed, excluded from retry_breakdown. Null when unavailable.
total_call_attemptsTotal Call Attempts | null
Every dial placed, retries and follow-ups included. Duplicate legs excluded. Null when unavailable.
retry_policyRequiredRetry Policy
The policy these numbers ran under.
400
1000 — malformed or contradictory input: an unknown timezone, a working-hours window that is not 24-hour HH:MM, an end_time at or before start_time, or an empty patch body. 1002 — a required parameter is missing.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
401
1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
403
1102 — the key is valid but lacks the scope this endpoint requires, or names another organisation. GET /v2/scopes reports which scopes the key holds.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
404
1200 — no such campaign, or no such agent, in this organisation. A campaign belonging to another organisation answers 404, never 403, so ids cannot be probed.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
422
1001 — the body or query failed validation; the message names the first offending field.
errorRequiredinteger
Stable integer code from the error table. Branch on this, not on the message.
messageRequiredstring
One human-readable sentence. Wording may change; the code will not.
429
1300 — per-organisation rate limit exceeded. Carries Retry-After.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
503
1501 — the agent service is unreachable or returned a 5xx.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
504
1502 — the agent service did not respond in time.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
Live contact, batch and call numbers for this campaign.

