Dispositions
Purpose
Section titled “Purpose”Describe dispositions: the outcome codes that classify a call attempt and drive retries, closure and DNC.
Overview
Section titled “Overview”A disposition code (disposition_codes) is the server-side source of truth
for a call’s outcome. Each code carries is_terminal, adds_to_dnc,
default_retry_delay_seconds and is_conversion — never trusted from the
client. Recording an attempt happens in a single transaction: insert the
lead_attempts row, add to DNC if the code requires it (fail-closed), transition
the lead (terminal → closed; non-terminal → attempted with a computed
next_attempt_at), enforce the attempt cap, and write an audit entry.
The seeded default taxonomy:
- Terminal:
sale,not_interested,do_not_call,wrong_number,invalid_number. - Non-terminal:
no_answer,busy,voicemail,answering_machine,callback.
Only do_not_call adds to DNC.
Configuration
Section titled “Configuration”Campaigns offer codes either per-campaign (campaign_dispositions) or via a
reusable named list (disposition_lists, set on campaigns.disposition_list_id).
Resolution order: list → campaign codes → tenant defaults. A referenced code
cannot be deleted (FK ON DELETE RESTRICT).
Retry timing for a non-terminal code: an explicit callback time wins, else the
most specific campaign_retry_cadence rule for the disposition and attempt
number, else the code’s default_retry_delay_seconds. With snap_to_window,
the next attempt advances to the next valid calling window in the lead’s
timezone.
Examples
Section titled “Examples”| Disposition | Terminal | Effect |
|---|---|---|
| sale | yes | Lead closed; counts as conversion |
| callback | no | Schedules a future attempt (default 3600s) |
| no_answer | no | Retry after cadence (default 14400s) |
| do_not_call | yes | Closes lead and adds number to DNC |
- The call engine also records operational dispositions itself:
no_route,originate_failed,abandoned,voicemail, and maps unanswered carrier legs from the Q.850 hangup cause (USER_BUSY→busy,NO_ANSWER→no_answer). amd_resultis stored asNULL(not'') — queries useCOALESCE(amd_result,'')so human-answered counts and the abandonment rate aren’t silently zeroed.