Call attribution (Twilio DNI)
Owner: Ops / Twilio
Endpoints: POST /v1/collect, POST /v1/identify
Status: ⚠️ not yet implemented. The endpoints exist; DNI pool matching
and call-source resolution are scheduled work. This page documents the intended
contract so the Twilio side can be built in parallel — treat the payloads as a
proposal open to change, not a shipped API.
The problem this solves
Section titled “The problem this solves”Phone-in leads have loose source data. Rather than pretend otherwise, Stitch gives every touchpoint a certainty tier and lets any report be sliced or stress-tested by it:
| Tier | Meaning | Typical call source |
|---|---|---|
| A | Deterministic | — |
| B | Strong | — |
| C | Inferred | A call to a number in a known DNI pool |
| D | Declared | “I saw you on Instagram” |
| E | Unknown | A direct call to the main line |
Today, phone-in leads land at tier E. DNI moves them to tier C, and the voice agent capturing source conversationally moves them to tier D. Both are real improvements on nothing.
What we need from the Twilio side
Section titled “What we need from the Twilio side”- A number pool per channel or partner. One tracked number per campaign or partner, mapped to a pool name.
- A call event on answer, carrying the dialled number and the caller’s number.
- The pool registry, so Stitch can resolve a dialled number to a channel.
Proposed call event
Section titled “Proposed call event”curl -X POST https://stitch-collector-dev.magic-blocks.workers.dev/v1/collect \ -H "content-type: application/json" \ -d '[{ "event_id": "twilio-CA1234567890", "ts": 1772539200000, "name": "call_start", "url": "https://makeabeeline.com/", "referrer": null, "props": { "dialled_number": "+14155550199", "dni_pool": "pool-12-gads-dscr", "call_sid": "CA1234567890", "direction": "inbound" } }]'A matched dni_pool produces a Paid Call — {pool} channel at certainty
tier C.
Declared source from the voice agent
Section titled “Declared source from the voice agent”When a voice agent asks how someone heard about us, that answer is worth capturing as a tier D signal with a transcript reference:
{ "declared_source": "Instagram", "transcript_ref": "mb-sess-77120#t=42" }Why declared source is worth capturing even though it is weak
Section titled “Why declared source is worth capturing even though it is weak”Cross-tabbing tier D against tier A for the same loan produces the declared-vs-tracked matrix. Where a borrower says “Google” and we hold a Meta click ID, that cell quantifies brand halo and view-through influence — things otherwise invisible. This one report usually reframes a media budget.
Open questions for ops
Section titled “Open questions for ops”- How many tracked numbers can we reasonably operate?
- One number per campaign, or per partner? Per campaign is more precise and more work to maintain.
- Can the voice agent reliably ask the source question without hurting the conversation?