Skip to main content

Campaign Service

Add or Create Contacts in Campaign

Request Body

Each contact in the contacts array should have the following fields: Note: A contact already enrolled in the campaign is not enrolled again, and a re-add never schedules a second call. If you re-submit an already-enrolled contact in the contacts array with new variables, those variables are refreshed on the existing enrollment, and custom_fields on a matched contact are merged and updated. Only the enrollment (and any pending call) is left untouched.

Duplicate phone numbers

By default (allow_duplicate_phone omitted or false), a contacts entry whose phone number already exists in your workspace does not create a second contact. The most recently created matching contact is reused (its custom_fields/variables are refreshed) and enrolled. If more than one existing contact shares that phone, the newest is chosen and a multiple_matches entry is added to the response contact_warnings array. This default protects against a retried request creating duplicate contacts and placing duplicate calls. Set allow_duplicate_phone: true when you genuinely want a new, distinct contact even though the phone already exists (the platform allows multiple contacts to share a number, the same as the app UI). With it enabled, every contacts entry is created as a new contact and enrolled, and its id appears in added_contact_ids.
  • The flag only affects the contacts array. contact_ids are unaffected.
  • When enabled, no phone matching happens, so no multiple_matches entry is ever added to contact_warnings.
  • Caution: because each request creates new contacts, retrying the same request with allow_duplicate_phone: true creates additional contacts and places additional calls. Use it only for genuinely distinct people, and do not use it as a blind retry.
  • If the value is not a boolean, the request fails with a 400.
Example: create a distinct new contact on a number that already exists.
The new contact’s id appears in added_contact_ids, and there is no contact_warnings entry even though the phone was already in use.

Variables and prompt personalization

Campaign calls support the same {{var.KEY}} prompt substitution as the direct call endpoint. Per-contact variables (inside a contacts entry) are stored on the campaign enrollment and injected into every call the campaign places to that contact — including calls deferred by quiet hours and later steps of a multi-step campaign. They are not used for SMS steps. Variables are only accepted on contacts entries. Contacts enrolled via contact_ids carry no variables — to attach variables to an existing contact’s calls, set values on the contact’s custom_fields instead (those render as {{custom.<key>}} and apply to every call with the contact). Constraints (same as the call endpoint): at most 50 keys, keys must match ^[a-zA-Z][a-zA-Z0-9_]{0,62}$, values up to 1000 characters, whole object under 4KB serialized. Violations fail the request with a 400. In your agent prompt or greeting, reference variables as {{var.KEY}}:
Hi {{var.lead_name}}, this is about your {{var.product}} appointment on {{var.appt_time}}.

Custom fields

custom_fields values are validated against the field definitions configured in your workspace (Portal → Contacts → Custom Fields) and stored on the contact itself. Stored values can be referenced in agent prompts and greetings as {{custom.<key>}} — on every call with that contact, not just campaign calls. Validation is drop-and-report: keys that are not defined in your workspace, archived, or reserved — and values that fail the field’s type validation — are dropped while the contact is still created and enrolled. Every dropped entry is reported in the custom_field_warnings array of the response, with the contact’s index and phone for correlation. Warning codes: unknown_key, archived_key, reserved_key, type_mismatch, option_invalid, too_long, empty_value. Custom fields vs variables:

Example Request

In this example, every campaign call to John renders {{var.appt_time}} and {{var.quote_amount}} in the agent prompt; the existing contact enrolled by ID gets no variables.

Response

custom_field_warnings is present only when at least one custom_fields entry was dropped.