Lead Lists
Purpose
Section titled “Purpose”Describe lead lists and leads: the contacts a campaign dials, how they are imported, and how they move through their lifecycle.
Overview
Section titled “Overview”A lead list (lead_lists) is a named set of contacts attached to a
campaign, with its own caller_id (the CLI presented when dialing its leads). A
disabled list (active = false) contributes zero dialable leads.
Each lead (leads) holds phone_numbers (JSONB, ≥1), a primary_phone, a
resolved timezone, an attempt_count, a next_attempt_at (NULL = eligible
now), and arbitrary CSV columns in attributes. A lead’s state moves
fresh → attempted → contacted → closed; closed is absorbing, so a closed
lead is never re-dialed.
Configuration
Section titled “Configuration”Lists are uploaded and managed in the tenant app (and the /campaigns/{id}/lead-lists
endpoints). The CSV importer creates one fresh lead per row with ≥1 parseable
phone number, mapping a timezone column when present (else the campaign default),
and reports per-row rejections.
Examples
Section titled “Examples”phone,first_name,last_name,timezone+15551230001,Ada,Lovelace,America/New_York+15551230002,Alan,Turing,America/ChicagoThe pacer selects eligible leads (state IN ('fresh','attempted'), not
excluded, next_attempt_at due, not on DNC) and atomically claims each
one — the claim flips it to attempted and sets a short lock so no two pacer
ticks (or edges) dial the same lead.
- Numbers are normalized; the DNC anti-join compares on digits with the leading
+stripped, so+441…and441…match. - Per-lead
timezonedrives calling-window compliance — carry it where possible. - Optimistic concurrency (
version) resolves the pacer-vs-admin edit race.