Updated · by the Nerro team
API reference
Campaign people
Add up to 5,000 people who agreed to hear from you to a draft campaign, and follow each person's progress.
POST /campaigns/{id}/contacts
Adds people to a draft campaign. Once it's launched, start a new campaign for more people, so your consent statement covers everyone.
consent_source: how they agreed.web_form(a form on your website or ad),inbound_inquiry(they called, texted or emailed you first),customer_opt_in(existing customers who agreed) orevent_signup(an event or open house).consent_confirmed: must betrue. It's your statement that every person agreed to hear from you.contacts: 1 to 5,000 people:phone, an optionalname, and optionalvariablesfor the brief.
{
"consent_source": "inbound_inquiry",
"consent_confirmed": true,
"contacts": [
{ "phone": "+13125550101", "name": "Dana Lee", "variables": { "unit": "4B" } },
{ "phone": "(312) 555-0102", "name": "Lee Park" }
]
}{ "data": { "added": 2, "duplicates": 0, "invalid": 0 } }Numbers already in the campaign count as duplicates; ones that aren't phone numbers count as invalid. Do-not-call, calling-hours and recently-called checks run before each call, and anyone held back shows up as blocked below.
GET /campaigns/{id}/contacts
Each person's progress:
{
"data": [
{
"phone": "+13125550101", "name": "Dana Lee", "variables": { "unit": "4B" },
"status": "done", "blocked_reason": null, "attempts": 1,
"outcome": "callback", "callback_at": "2026-11-04T22:00:00.000Z", "last_call_id": "c1d2…"
}
]
}status:pending,due,dialing,waiting(between tries),done,blockedorcancelled.blocked_reason: why a person can't be called, like being on a do-not-call list.outcome:interested,callback,not_interested,no_answeroropted_out.last_call_id: look the call up in GET /calls.
Still stuck? Email support@nerro.si. A person replies within 24 business hours.
