vicigeeksimple guides
Browse
Data and integrations

VICIdial & agents · Worked integration guide

Reconcile pay-per-call attribution and contract eligibility

Work through nine fictional calls, expose unmatched and duplicate attribution, apply one explicit contract predicate, and export the same qualified rows used by the summary.

Start the guide

01 / 10

Start with a reconciled population, then apply the contract

Finish this exercise with an explained row for every call and a candidate export that uses the same rules as the summary. The downloadable records are fictional; they do not establish that a real buyer owes a payment.

Keep three questions separate: which source owns the call, which measured facts exist, and which contract predicates those facts satisfy. A termination category such as CALLER or AGENT does not prove that a person answered. A stored disposition is an input to review, not a universal definition of a billable call.

  1. Download and extract the complete exercise ZIP into one working directory, or save the individual files below together. Do not import these files into VICIdial.
  2. Write down the exact source population and time window before looking at the expected answer.

You should seeYou have nine fictional call rows and nine attribution rows to reconcile; one call is outside the selected window.

Download the complete reconciliation exercise (ZIP)

Download the complete exercise notes

Download fictional calls

Download fictional attribution rows

Download the local classifier

02 / 10

Define one call identity and inspect the join

The fixture uses a guaranteed unique call_id. Your installation needs its own reviewed call-leg identity and source mapping; lead_id alone can join several calls by the same lead. Inspect one-to-many and missing matches before summing duration or money.

C004 has two source matches and must be held for review. C005 has none. Neither is silently assigned to the most convenient source. The example keeps both anomalies visible while evaluating the six unambiguous in-window calls.

Expected attribution reconciliationScroll sideways to compare columns
PopulationCountMeaning
Raw call rows9Before window filtering
Outside window1C009 is exactly at the excluded end
In-window calls8The denominator for this exercise
Exactly one source match6Eligible for the next checks, not automatically billable
Ambiguous source1C004: two attribution rows
No source match1C005: keep unresolved

03 / 10

Step 1 — Record source ownership at the call time

For real inbound work, record the DID/source mapping and its effective period. A dedicated DID per source is one possible attribution design; an agent-selected label or today’s DID assignment is not proof of the historical source.

For this exercise, open attribution-fictional.csv. Confirm C001 maps once to SOURCE_A, C004 maps twice, and C005 is absent. Preserve these defects so the reconciliation can detect them.

  1. Check the raw call key is unique. Stop on duplicate base rows before joining.
  2. Count attribution matches per call: zero, one or more than one.
  3. Keep raw and mapped counts side by side; do not use an inner join that hides unmatched calls.

You should see8 = 6 uniquely attributed + 1 ambiguous + 1 unmatched. Investigate any failure of that equality.

04 / 10

Step 2 — Keep routing evidence separate from attribution arithmetic

If the real task includes configuring inbound service, complete Route a test DID to an in-group before collecting call evidence. Reopen the saved DID destination, confirm the intended in-group and agent membership, then perform the approved inbound functional test in that guide.

A DID configuration row does not prove that a caller reached an agent or that the contract was satisfied. This local worksheet starts from fictional call evidence and performs no carrier or routing change.

You should seeThe routing task has its own observed pass/blocked result; it is not inferred from this spreadsheet.

Route a test DID to an in-group

05 / 10

Step 3 — Give every qualification input a source

The teaching contract requires at least 60 connected seconds, a reviewed qualification, no duplicate flag, and a completed review flag. SOURCE_A and SOURCE_B have invented USD rates of 12.50 and 18.00. These values teach the calculation; they are not market prices or a standard contract.

connected_seconds is an explicitly supplied fictional measurement. Do not rename VICIdial length_in_sec as connected time without proving how it is measured on your build. The consent_reviewed input is not a legal conclusion. Apply the actual signed contract and relevant review requirements to real records.

The complete TRAINING-1 predicateScroll sideways to compare columns
InputRequired valueIf unavailable
Window2026-11-06 00:00:00 UTC inclusive to November 7 exclusiveResolve timezone and scope
AttributionExactly one reviewed sourceQuarantine missing/ambiguous matches
Connected durationAt least 60 secondsObtain the correct measurement
Qualification / duplicate / reviewY / N / YKeep excluded or unresolved
RateA: USD12.50; B: USD18.00Do not substitute zero or a guessed price

06 / 10

Step 4 — Run the same predicate for the summary and export

Run the downloaded classifier from its directory. It reads only the two local CSVs and creates a new output directory. It never connects to VICIdial or creates an invoice.

Open every decision row before accepting the total. C002 is short, C003 is unqualified, C006 is duplicate and C007 lacks the required review; C004 and C005 remain attribution exceptions.

Before you use it
Download reconcile.py and both input CSVs. Use a fresh results directory; pass --output another-name to retain a later run.
Classify the fictional contract
python3 -B reconcile.py
Evidence · Local fictional CSV reconciliation only; no VICIdial query, buyer review, invoice or network request.

Captured demo response · 2026-11-06T22:50:57.297900+00:00. Any filtering, hidden values or test-only data are identified in the capture label. Select Replay transcript to read the recorded output.

Command output line: python3 -B reconcile.py
{
"raw_rows": 9,
"excluded_window": 1,
"in_window": 8,
"unique_attribution": 6,
"ambiguous_attribution": 1,
"unmatched_attribution": 1,
"candidate_billable": 2,
"candidate_amount_usd": "30.50"
}
Success looks like
The result is 9 raw / 8 in-window / 6 unique-attribution calls, with 2 candidate-billable calls totaling fictional USD30.50.
Stop if
Stop on repeated call IDs, missing fields, invalid values or an existing output directory. Keep unknown facts unresolved.

You should seecandidate-billable.csv contains C001 and C008 only. Their amounts are 12.50 and 18.00, totaling 30.50; the summary and export are derived from the same decisions.

07 / 10

Step 5 — Reconcile by identity, not just by grand total

Compare your output with the expected files. A different row set with the same total is still a discrepancy. In real work, exchange only the agreed minimal evidence: stable call reference, source, window, measured duration basis, qualification decision, contract version and dispute reason.

Keep an unfiltered call-log export labelled raw evidence. The optional query below is a read-only inventory; it deliberately does not label its rows billable or its duration connected. Confirm the database timezone and installed schema before using it.

Before you use it
Use the authorized client from Create a read-only database account for safe VICIdial queries. Confirm that these database-local dates represent your agreed window and that the listed columns exist.
Raw inbound evidence, not a billable export
SELECT closecallid, uniqueid, lead_id, campaign_id, status, call_date,       length_in_sec AS logged_length_seconds, term_reasonFROM vicidial_closer_logWHERE call_date >= '2026-11-06 00:00:00'  AND call_date < '2026-11-07 00:00:00'ORDER BY closecallid;
Reader-run example · not executed for this guide

This example has no recorded result here. Follow its preparation, expected result and stop conditions before using it.

Success looks like
You obtain raw candidate evidence for review, including stable row identity and honestly named logged duration.
Stop if
Stop if the timezone, schema or call-leg identity is unclear. This query applies no contract qualification predicates.

Expected decision for every row

Expected candidate export

Expected summary

08 / 10

Explain different, missing and unknown results

If raw rows do not split into inside/outside-window rows, fix the boundary or timezone. If in-window rows do not split into zero/one/many attribution matches, inspect the join. If the candidate export differs from the summary, stop billing and make both use one decision result.

Where to investigate nextScroll sideways to compare columns
ObservationNext action
Duplicate base keyResolve export duplication before joining
Two source matchesReview mapping history; preserve the disputed call
No source matchFind missing source evidence; do not invent a source
CALLER or AGENT onlyTreat as termination category; seek qualification evidence
Different buyer countCompare IDs, filters, timezone, thresholds and duplicate rules

09 / 10

Stop changes without destroying the evidence

A data discrepancy is not itself authorization to change a live DID or campaign. Have the routing owner use the relevant guide if a source must be paused; record the old destination and the exact authorized change.

For this offline exercise, no server rollback is needed. Keep the inputs, output and contract version together. A corrected mapping is a new reviewed run; retain the old result so a reviewer can explain the change.

You should seeYou can explain all nine input rows and identify exactly which two meet the fictional contract. Real contract acceptance remains a separate review.

10 / 10

Use the same discipline for reports and integrations

Continue with Scope and check a VICIdial User Stats report for metric scope, or VICIdial Call URLs: a durable local receipt lab for a bounded event-receipt exercise. Do not let a successful event delivery or a large call count stand in for the qualification evidence your contract requires.

Checks and sources

What was checked

  • The nine-row fixture and classifier were executed locally; expected decisions include missing/ambiguous attribution and the exclusive end boundary.
  • The SQL inventory is a reviewed template, not a newly captured database query or proof of billability.
  • No real buyer contract, inbound attribution chain or billable-call screenshot was captured for this exercise. The demonstrated output is the local synthetic reconciliation, not a carrier or billing result.

Primary references

Sources

  1. VICIdial Non-Agent APIVICIdial · accessed November 6, 2026
  2. VICIdial Call URL featuresVICIdial · accessed November 6, 2026