Campaigns
List campaigns
GET /v1/campaigns campaigns:read
Responses
- 200
The campaigns of this environment
Fields
-
dataCampaign[] requiredFields
-
idstring required -
namestring required -
versionstring required -
hooksstring[] requiredThe hooks this version defines
-
stepsobject[] requiredThe sequence, in order
-
enrollmentobject requiredIts
.enroll: which leads it takes by itself, and whether a lead that left can start over -
status"running" | "paused" required -
pausedReason"manual" | "not_started" | "hook_failing" | "needs_deploy" | "needs_deploy_held" | "billing" | null required -
countsobject requiredLeads per state,
dials, andexit_<reason>for how leads left. Kept as counters, so reading it is cheap. -
warningsstring[]On a deploy: what this change does to leads mid-sequence.
-
createdAtstring required -
updatedAtstring required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Register campaigns
PUT /v1/campaigns campaigns:write
What hcc deploy sends. A campaign is its name and which hooks it defines; the logic is in your code. A new campaign starts paused in every environment, until someone resumes it, and a deploy never changes the status of one that exists.
Body
-
campaignsobject[] requiredFields
-
namestring required -
versionstring required -
hooks"onLead" | "call" | "do" | "goal" | "exit" | "afterCall" | "screenPop" | "onAnswer" | "onVoicemail" | "onNoAnswer" | "onError"[] required -
stepsobject[]Default
[{"kind":"call","target":{"type":"queue"}}].Fields
call
-
kind"call" required -
namestring -
targetobject required -
fromstring
wait
-
kind"wait" required -
namestring -
msinteger required
do
-
kind"do" required -
namestring
-
-
enrollmentobjectFields
-
whereobjectDefault
{}. -
reenrollbooleanDefault
true.
-
-
flowobject requiredFields
-
namestring required -
versionstring required -
timeoutMsinteger100 to 5000.
-
inputSchemaobject -
stateSchemaobject -
handlers"call.answered" | "call.no_answer" | "call.voicemail" | "call.hangup" | "call.gather" | "call.agent.tool" | "call.agent.ended" | "call.agent.summary" | "call.custom" | "call.transfer.failed" | "call.error"[]Default
[]. -
customEventsstring[]Default
[]. -
fallbacksobjectDefault
{}. -
toolsobject[]Default
[]. -
agentsobject[]Default
[].
-
-
-
mode"report" | "deploy"Default
"report". -
endpointUrlstring -
alsoTestbooleanDefault
false.
Responses
- 200
The registered campaigns
Fields
-
dataCampaign[] requiredFields
-
idstring required -
namestring required -
versionstring required -
hooksstring[] requiredThe hooks this version defines
-
stepsobject[] requiredThe sequence, in order
-
enrollmentobject requiredIts
.enroll: which leads it takes by itself, and whether a lead that left can start over -
status"running" | "paused" required -
pausedReason"manual" | "not_started" | "hook_failing" | "needs_deploy" | "needs_deploy_held" | "billing" | null required -
countsobject requiredLeads per state,
dials, andexit_<reason>for how leads left. Kept as counters, so reading it is cheap. -
warningsstring[]On a deploy: what this change does to leads mid-sequence.
-
createdAtstring required -
updatedAtstring required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Get a campaign
GET /v1/campaigns/{name} campaigns:read
Path
namestring required
Responses
- 200
The campaign
Fields
-
dataCampaign requiredFields
-
idstring required -
namestring required -
versionstring required -
hooksstring[] requiredThe hooks this version defines
-
stepsobject[] requiredThe sequence, in order
-
enrollmentobject requiredIts
.enroll: which leads it takes by itself, and whether a lead that left can start over -
status"running" | "paused" required -
pausedReason"manual" | "not_started" | "hook_failing" | "needs_deploy" | "needs_deploy_held" | "billing" | null required -
countsobject requiredLeads per state,
dials, andexit_<reason>for how leads left. Kept as counters, so reading it is cheap. -
warningsstring[]On a deploy: what this change does to leads mid-sequence.
-
createdAtstring required -
updatedAtstring required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Pause a campaign
POST /v1/campaigns/{name}/pause campaigns:write
No new dials. Calls already up carry on.
Path
namestring required
Responses
- 200
The campaign
Fields
-
dataCampaign requiredFields
-
idstring required -
namestring required -
versionstring required -
hooksstring[] requiredThe hooks this version defines
-
stepsobject[] requiredThe sequence, in order
-
enrollmentobject requiredIts
.enroll: which leads it takes by itself, and whether a lead that left can start over -
status"running" | "paused" required -
pausedReason"manual" | "not_started" | "hook_failing" | "needs_deploy" | "needs_deploy_held" | "billing" | null required -
countsobject requiredLeads per state,
dials, andexit_<reason>for how leads left. Kept as counters, so reading it is cheap. -
warningsstring[]On a deploy: what this change does to leads mid-sequence.
-
createdAtstring required -
updatedAtstring required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Resume a campaign
POST /v1/campaigns/{name}/resume campaigns:write
Dials again, within calling hours and pacing. Refused with a 409 while the campaign needs a deploy.
Path
namestring required
Responses
- 200
The campaign
Fields
-
dataCampaign requiredFields
-
idstring required -
namestring required -
versionstring required -
hooksstring[] requiredThe hooks this version defines
-
stepsobject[] requiredThe sequence, in order
-
enrollmentobject requiredIts
.enroll: which leads it takes by itself, and whether a lead that left can start over -
status"running" | "paused" required -
pausedReason"manual" | "not_started" | "hook_failing" | "needs_deploy" | "needs_deploy_held" | "billing" | null required -
countsobject requiredLeads per state,
dials, andexit_<reason>for how leads left. Kept as counters, so reading it is cheap. -
warningsstring[]On a deploy: what this change does to leads mid-sequence.
-
createdAtstring required -
updatedAtstring required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
A campaign's latest backfill
GET /v1/campaigns/{name}/backfill campaigns:read
Path
namestring required
Responses
- 200
The latest run, or null if there has been none
Fields
-
dataany required
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Run existing leads through a campaign
POST /v1/campaigns/{name}/backfill campaigns:write
Runs each lead that matches the campaign's filter, from its .enroll, through its onLead. With no onLead it takes them all, in the database, with no call to your server. It works while the campaign is paused, and nothing dials until it runs: while it's running, the leads it enrolls can be dialed straight away. A lead already in the campaign stays where it is, a lead that left stays out, and a removed lead comes back only if onLead enrolls it and the campaign doesn't say reenroll: false, so it's safe to repeat. It runs only when you ask, never on a deploy or a resume. A 409 if one is already running for this campaign, or if the campaign needs a deploy.
Path
namestring required
Body
CampaignBackfillRequest
Responses
- 202
Started. Follow it with GET
Fields
-
dataCampaignBackfill requiredFields
-
idstring required -
campaignstring required -
status"running" | "done" | "failed" | "cancelled" requiredfailedmeans the flow endpoint kept failing and it stopped early: retry goes on from where it was. Adonerun can still havefailedleads, which a retry sends again. -
whereobject | null requiredThe campaign's filter when it started
-
leadsInScopeinteger requiredHow many leads the environment had when it started. The count stops at 1,000,000: see
leadsInScopeCapped. -
leadsInScopeCappedboolean required -
scannedinteger requiredLeads walked, matching the filter or not
-
checkedinteger requiredLeads that matched.
enrolled+skipped+failedreaches this once nothing is on its way. -
enrolledinteger requiredLeads new to the campaign
-
skippedinteger requiredAlready in it, left for good, on your Do Not Call list, or
onLeadsaid no -
failedinteger requiredLeads with no answer, after retries
-
failurestring | null requiredWhy the latest batch was given up on
-
retryReasonstring | null requiredWhat it can't do just now and keeps trying. Only while it's
running -
createdAtstring required -
updatedAtstring required -
finishedAtstring | null required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Stop a backfill
POST /v1/campaigns/{name}/backfill/cancel campaigns:write
What was enrolled stays. A 409 if none is running. A batch being answered at that moment can still enroll its leads.
Path
namestring required
Responses
- 200
The run
Fields
-
dataCampaignBackfill requiredFields
-
idstring required -
campaignstring required -
status"running" | "done" | "failed" | "cancelled" requiredfailedmeans the flow endpoint kept failing and it stopped early: retry goes on from where it was. Adonerun can still havefailedleads, which a retry sends again. -
whereobject | null requiredThe campaign's filter when it started
-
leadsInScopeinteger requiredHow many leads the environment had when it started. The count stops at 1,000,000: see
leadsInScopeCapped. -
leadsInScopeCappedboolean required -
scannedinteger requiredLeads walked, matching the filter or not
-
checkedinteger requiredLeads that matched.
enrolled+skipped+failedreaches this once nothing is on its way. -
enrolledinteger requiredLeads new to the campaign
-
skippedinteger requiredAlready in it, left for good, on your Do Not Call list, or
onLeadsaid no -
failedinteger requiredLeads with no answer, after retries
-
failurestring | null requiredWhy the latest batch was given up on
-
retryReasonstring | null requiredWhat it can't do just now and keeps trying. Only while it's
running -
createdAtstring required -
updatedAtstring required -
finishedAtstring | null required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Retry a backfill's failures
POST /v1/campaigns/{name}/backfill/retry campaigns:write
Sends its failed leads again and, if it stopped early, walks on from where it was. A 409 if one is running, or there is nothing to retry.
Path
namestring required
Responses
- 200
The run
Fields
-
dataCampaignBackfill requiredFields
-
idstring required -
campaignstring required -
status"running" | "done" | "failed" | "cancelled" requiredfailedmeans the flow endpoint kept failing and it stopped early: retry goes on from where it was. Adonerun can still havefailedleads, which a retry sends again. -
whereobject | null requiredThe campaign's filter when it started
-
leadsInScopeinteger requiredHow many leads the environment had when it started. The count stops at 1,000,000: see
leadsInScopeCapped. -
leadsInScopeCappedboolean required -
scannedinteger requiredLeads walked, matching the filter or not
-
checkedinteger requiredLeads that matched.
enrolled+skipped+failedreaches this once nothing is on its way. -
enrolledinteger requiredLeads new to the campaign
-
skippedinteger requiredAlready in it, left for good, on your Do Not Call list, or
onLeadsaid no -
failedinteger requiredLeads with no answer, after retries
-
failurestring | null requiredWhy the latest batch was given up on
-
retryReasonstring | null requiredWhat it can't do just now and keeps trying. Only while it's
running -
createdAtstring required -
updatedAtstring required -
finishedAtstring | null required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
List a campaign's leads
GET /v1/campaigns/{name}/leads campaigns:read
Path
namestring required
Query
state"queued" | "waiting" | "needs_timezone" | "needs_consent" | "claimed" | "in_call" | "acting" | "deciding" | "step_failed" | "done"limitintegercursorstring
Responses
- 200
The most recently changed first
Fields
-
dataCampaignLead[] requiredFields
-
leadIdstring required -
phonestring required -
namestring | null required -
state"queued" | "waiting" | "needs_timezone" | "needs_consent" | "claimed" | "in_call" | "acting" | "deciding" | "step_failed" | "done" required -
priorityinteger required -
attemptsinteger required -
nextAttemptAtstring required -
lastOutcomestring | null required -
stepinteger requiredWhere it is in the sequence, or what is next
-
stepNamestring | null required -
exitReason"goal" | "exit" | "finished" | "removed" | "do_not_call" | null requiredWhy it left, once it has
-
-
nextCursorstring | null required
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Put leads in a campaign
POST /v1/campaigns/{name}/leads campaigns:write
Straight in line, past onLead, if they match the campaign's filter and aren't on your Do Not Call list. A lead already in the campaign stays put.
Path
namestring required
Body
-
leadIdsstring[] required -
priorityinteger0 to 1000.
Responses
- 200
How many were new to it, and how many the campaign's filter or your Do Not Call list turned away
Fields
-
dataobject requiredFields
-
enrolledinteger required -
skippedinteger required
-
-
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Take a lead out of a campaign
DELETE /v1/campaigns/{name}/leads/{leadId} campaigns:write
The lead stays. A dial it was ready for is dropped before it happens.
Path
namestring requiredleadIdstring required
Responses
- 204
Removed
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code
Try a parked lead again
POST /v1/campaigns/{name}/leads/{leadId}/retry campaigns:write
A lead parked as step_failed goes back to the step it stopped at, within a minute. For a lead parked just after a call, that means another dial.
Path
namestring requiredleadIdstring required
Responses
- 202
On its way
- 400
Invalid request
- 401
Missing or invalid API key
- 404
Not found
- 429
rate_limited, or another limit named byerror.code