Skip to main content

Creating a campaign

One request does three things: it creates the campaign, accepts the planned calls and — if every launch check passes — starts dialing. There is no separate “start” step in the happy path.

Headers

Request body

Unknown top-level keys are ignored. Fields that exist on the campaign but are not settable through /v1 (frequency_override, dashboard-only presets) are silently ignored if sent.

Order of refusals on creation

Before the campaign exists (the idempotency slot is released, a corrected retry with the same key is fine):
  1. 422 invalid_request — body fails the schema (missing name, agent_id or calls_per_minute, wrong types).
  2. 422 idempotency_key_required, 422 dnc_decision_invalid.
  3. 422 idempotency_key_reuse / 409 idempotency_key_in_flight / replay of the earlier answer.
  4. 422 campaign_window_invalid, then 422 campaign_open_ends_at_required / campaign_open_ends_at_too_far.
  5. 422 campaign_agent_unknown, 422 campaign_timezone_unknown.
  6. Dialing binding: 422 dialing_route_unresolved / dialing_route_ambiguous / dialing_binding_incomplete.
  7. 422 working_hours_wider_than_law.
  8. Repository validation: 422 campaign_spec_invalid (tier, retry configuration, working-hours form, duplicate action, name length), 422 campaign_classification_invalid.
After the campaign exists (the slot is kept — a retry with the same key answers 409 idempotency_key_in_flight; find the campaign with GET /v1/campaigns):
  1. Planned calls: 409 market_package_not_installed, 502 contact_file_storage_unavailable, 422 contact_rows_rejected (the rows could not be stored at all — distinct from rows rejected by the parser, which are reported inside import with a 201).
  2. Launch: 409 campaign_transition_invalid (unexpected state race).

Success response — 201 Created

The response is always 201 when the campaign was created, whether or not dialing began. The single source of truth about that is status.