Campaign runs
GET /api/v1/campaign/{id}/runs — paginated call records for a campaign.
GET /api/v1/campaign/{campaign_id}/runsPaginated list of the campaign's call records. Each row is one call (or attempt) produced by the campaign, drawn from the unified calls table.
Query parameters
| Param | Type | Default | Notes |
|---|---|---|---|
page | int | 1 | 1-based page number. |
limit | int | 50 | Rows per page. |
filters | string (JSON) | — | JSON-encoded array of filter objects. Each object's attribute must be one of dateRange, dispositionCode, duration, status, tokenUsage — any other attribute returns 403. |
sort_by | string | — | Field to sort by. Only created_at is honored; any other value falls back to created_at. |
sort_order | string | desc | asc or desc. asc is only applied together with sort_by=created_at. |
Response
{
"runs": [
{
"id": 12345,
"call_id": "call_abc123...",
"transport": "telephony",
"pipeline_source": "campaign",
"status": "completed",
"from_number": "+14155550100",
"to_number": "+14155559999",
"telephony_provider": "twilio",
"duration_seconds": 105,
"ended_reason": "user_hangup",
"connection_status": "completed",
"created_at": "2026-06-16T11:00:05Z",
"started_at": "2026-06-16T11:00:10Z",
"ended_at": "2026-06-16T11:01:55Z",
"context_variables": { "customer_name": "Aman", "order_id": "ORD-42" },
"usage_info": { }
}
],
"total_count": 500,
"page": 1,
"limit": 50,
"total_pages": 10
}context_variables is the per-call context (including the source-row values used to fill template variables). usage_info carries the per-call cost/usage breakdown.
Each run carries both outcome dimensions: connection_status (did the attempt connect — completed, or busy/no_answer/dial_failed/... — see connectionStatus values) and ended_reason (the connected-call vocabulary: user_hangup, agent_hangup, silence_timeout, max_duration, voicemail, transferred, pipeline_error, cancelled, unknown; null for attempts that never connected).
Examples
curl "https://dashboard.zoxa.ai/api/v1/campaign/7/runs?page=1&limit=50&sort_by=created_at&sort_order=asc" \
-H "X-API-Key: zsk_..."Filtering by a date range (the filters value is URL-encoded JSON):
curl -G "https://dashboard.zoxa.ai/api/v1/campaign/7/runs" \
-H "X-API-Key: zsk_..." \
--data-urlencode 'filters=[{"attribute":"status","value":"completed"}]'Errors
| Status | detail | When |
|---|---|---|
400 | "Invalid filter format" | filters isn't valid JSON. |
403 | "Invalid attribute '…'" | A filter attribute isn't in the allow-list. |
404 | "Campaign … not found" | campaign_id doesn't resolve in your org. |