DocsCall TrackingWarm Transfer (Pre-Call Data)

Warm Transfer (Pre-Call Data)

Send a caller's details right before a warm or live transfer and Lead Distro AI attaches them to the matching call automatically, for reporting, reconciliation, dispute review, and delivery on to your destination while the call is live. Works with any dialer that can send a quick GET or POST.

Last updated:

Call Tracking is in beta and turned on per account. If you don't see Calls in your left sidebar (or it shows a "Soon" tag), email support@leaddistro.ai and we'll switch it on for you.

A warm transfer (also called a live transfer) is when your source pre-qualifies a caller and then bridges the live call to your tracking number, instead of the caller dialing in cold. This guide shows how to send that caller's details a moment before the transfer, so Lead Distro AI can attach them to the call. For the basics of a call campaign first, see Call Tracking Setup.


When to use it

  • Your buyer pays per qualified or passed call, not per lead, so each call needs to be tied to who the caller was.
  • You want the caller's details (name, state, case type, TrustedForm, your own lead id) on the call record for reporting, reconciliation, and dispute review.
  • Your source runs a warm or live transfer through a dialer that can send a quick web request before it bridges the call.

How it works

  • Your source sends the caller's details to the call enrichment endpoint (a quick GET or POST) right before the transfer.
  • Your source bridges the live call to your campaign's tracking number.
  • Lead Distro AI matches the two by the caller's phone number and shows the details on the call record.

The one requirement: the transfer has to show the consumer's phone number as the caller ID (this is called ANI passthrough). That number is how we match the details to the call. If your dialer can only show its own number, email support@leaddistro.ai and we'll set you up with a dedicated number per lead instead.

The thing to hold onto: two separate things are travelling, and they do not wait for each other. The call goes over the phone line. The caller's details go over the internet, as their own web request. Nothing ties them together except the caller's phone number, which is why the order they arrive in matters, and why almost every problem on this page is really a question of which one got there first.


Step 1: Turn on Pre-call Data and choose your fields

Open your call campaign, go to Settings, and turn on Pre-call Data. A Fields tab appears where you choose which parameters to accept: add whatever your vertical needs (first name, state, case type, ZIP, your own lead id, anything). There is no fixed list. We always keep the caller's name, phone, and email; the Fields tab is for the extra fields you want stored and shown on the call.

The same card has a Wait for source data box. Leave it at 0 for now. It only matters when a destination refuses calls that arrive without the data, which has its own section further down.

Give a field the ZIP / Postal Code or State type and it does double duty: we store it AND can route the call by territory. See Geographic Routing.

Step 2: Send the caller details

Send the fields to the enrichment endpoint using the same API key your source already uses. You can send them as a POST with a JSON body, or as a GET with query values, whichever your dialer supports. The callerid is the consumer's phone in E.164 format (like +13105551234) and is required, since it's the key we match on.

curl -X POST https://app.leaddistro.ai/api/v1/calls/enrich \
  -H "x-api-key: YOUR_SUPPLIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flo_campaign_id": "YOUR_CAMPAIGN_ID",
    "flo_supplier_id": "YOUR_SUPPLIER_ID",
    "callerid": "+13105551234",
    "first_name": "Maria",
    "state": "TX",
    "case_type": "MVA",
    "trustedform_url": "https://cert.trustedform.com/...",
    "lead_id": "YOUR-LEAD-ID"
  }'

Prefer a simple GET? Send the same values as query parameters (send the x-api-key as a header, and URL-encode the + in callerid as %2B):

https://app.leaddistro.ai/api/v1/calls/enrich?flo_campaign_id=YOUR_CAMPAIGN_ID&flo_supplier_id=YOUR_SUPPLIER_ID&callerid=%2B13105551234&first_name=Maria&state=TX&case_type=MVA&lead_id=YOUR-LEAD-ID

On success you get back a confirmation of exactly what we stored and will match on:

{
  "success": true,
  "mode": "call_enrichment",
  "stored": true,
  "matched": false,
  "caller_phone": "+13105551234",
  "fields_stored": ["first_name", "state", "case_type", "trustedform_url"],
  "external_lead_id": "YOUR-LEAD-ID",
  "expires_at": "...",
  "match_window_hours": 48
}

Wait for this response before you transfer the call. Send the details, get the 200 back, then bridge. If the call reaches us first, it gets routed with an empty record: your buyer's filters see no state, no case type, nothing, and the call can be turned away for data you did in fact send.

stored: true only means we saved the details and opened the 48 hour match window. It is not a promise that they reached a call. That is what matched tells you. Posting before the transfer, matched is normally false, because the call has not arrived yet, and it becomes true when the call lands and picks the details up.

If the call beat your post, we say so instead of staying quiet about it:

{
  "success": true,
  "stored": true,
  "matched": false,
  "warning_code": "call_already_received",
  "warning": "A call from this number arrived 1.7s before this post, so it was routed without this data."
}

Seeing call_already_received means your dialer is bridging before it finishes posting. Fix the order in your dialer. Posting faster will not close the gap reliably, because it is a race you only win by accident.

Testing your setup? Add test=true and we'll reply with exactly what we parsed, without storing anything, so you can confirm the wiring before going live. You have 48 hours from sending the details to bridge the call.

Step 3: Bridge the live call

Send the live call to your campaign's tracking number, passing the consumer's phone number as the caller ID. When the call lands, we match it to the details you sent and attach them.

Step 4: Set the destination to bill on connect

Because your buyer pays for a passed transfer rather than talk time, set the destination to bill when the call connects. Open the destination in Edit Target, set billing to bill on connect with a 1 second minimum, and save. If a transfer doesn't qualify, refund that call from the call's page and it shows as Returned. See Wallet & Top-Ups.

Step 5: Send the details on to your destination (optional)

The details are on your call record either way. If your destination wants them too, in their CRM, or in an inbox while the call is still live, you have two options, and you can use both.

  • Data Delivery (per destination). Open the destination in Edit Target, turn on Data Delivery, and fill in the endpoint URL, method, any custom headers, and the body template. We post the caller's phone and location plus every pre-call field to their endpoint. Send Test fires a sample so you can validate their endpoint before a real call rings.
  • When to send picks the timing. On connect (the default) fires the moment that destination answers, and only to the destination that actually took the call. Before dial fires just before we ring each destination, so the data is usually in their hands when the phone rings. It is a head start, not a guarantee: we give the send a 0.8 second head start, then ring anyway rather than leave a live caller sitting in silence, and a slower endpoint gets the data a beat after its phone starts.
  • A Call Connected automation (campaign-wide). On the campaign's Overview tab, go to Triggers & Automations, add an automation with the Call Connected trigger, and choose the Email, Webhook, Slack, or Google Sheet action. The Fields picker includes a Pre-Call Data group, so you can drop the caller's fields straight into an email to your client.

If the source posts the details after the call already started, the Pre-Call Data Received Late trigger fires with the updated info, and Data Delivery re-sends too, so a late post still reaches your destination.


When a destination only takes calls that have the data

Some destinations will not accept a transfer unless the caller's details are already attached. That is a routing rule, not a delivery preference, and it takes two settings working together. Turn on only one and the destination turns away calls whose details you did in fact send.

This is the most common way a warm transfer setup fails, and it looks like it is working. Most call centers bridge the call first and post the details a second or two later, because the dialer connects while the CRM webhook is still firing. On one live campaign every announcement landed 2.5 to 3.1 seconds after the call. A destination that required the data rejected 100% of that source's real traffic, while the details still landed on the call record a moment later. Everything looked right except the one thing that mattered, the routing decision.

  • Add the rule on the destination. Open the destination in Edit Target, go to Call Filters, and add Precall Data Is Not Empty. That destination now only rings for calls a source announced.
  • Set the grace window on the campaign. In Settings, under Pre-call Data, set Wait for source data to 2 or 3 seconds. We hold the call just long enough for the details to land, then route. We check four times a second and stop waiting the instant they arrive, so the usual cost is your source's real lag, not the whole budget.

You need both. The wait only ever applies when a destination on that campaign is actually filtering on Precall Data, so seconds without the filter wait for nothing, and the filter without the seconds turns away every call your source announces a beat late.

A greeting or a recording notice plays during the wait, so most callers never notice it. The cap is 10 seconds, and 0 means never wait, which is how every campaign behaves until you change it.

Keep this number small. It is a live person sitting in silence, and people hang up on silence. If 2 or 3 seconds is not enough, the answer is not a bigger number, it is that your source is announcing too late and should be asking the destination before it bridges. That is the next section.


Telling versus asking

There are two ways to send a caller's details ahead of a call, and the difference between them is not technical. It is what you are actually saying to the destination.

What it is really saying
Enrichment endpoint"Here's who's calling." You are telling them.
RTB"Will you take this call, and what will you pay for it?" You are asking them.

Everything above on this page is telling. It is the right tool when the destination takes every call you send and simply wants to know who is on the line. The two settings in the last section make sure the telling arrives in time.

But telling has a ceiling: a filter can only screen a destination out of a call. It can never let that destination accept one, refuse one, or put a price on it. The moment your destination wants a say, you are asking, not telling, and asking is RTB. We send the caller's details to their bid endpoint and wait for the answer before anything rings, so a rejected transfer is one your source never bridges.

  • In Edit Target, set Routing method to Dynamic routing (RTB) and fill in their bid endpoint.
  • Set Ping when to Pre-call data arrives (pre-transfer). This is the setting that matters. We ping the destination the moment your source posts the caller's details, and your source gets the accept or reject in that same response, so it only bridges calls that were already accepted. Nobody is on the line yet, so the wait costs the caller nothing.
  • In Ping parameters, add each pre-call field with the Lead field source, so their bid request carries the same details your source announced.
  • Their response tells us whether they take it, what they pay, and which number to dial. If their endpoint only answers yes or no, set Target mode to Availability check and leave the forwarding number set, and we dial that.

Pre-transfer only fires for sources that actually announce. A source that bridges without ever posting to the enrichment endpoint never triggers the ping. Use Both if you have a mix: pre-transfer for the sources that announce, and a live ping when the call arrives for the ones that don't. On Call arrives, RTB reads the same pre-call record the filters do, so the grace window above still applies to that half.


Sending calls to another Lead Distro AI account

If your destination is another Lead Distro AI account, you are on both sides of this handoff: you send the call, they receive it on their tracking number. That works well, but there is one wiring mistake worth calling out, because it looks correct and fails silently.

Do not point Data Delivery at an enrichment endpoint while it is set to On connect. The receiving account's number picks up the instant the call lands, which is the same instant it decides where to route. So On connect does not send the details cleanly late, it sends them into a coin flip: sometimes they beat the routing decision, sometimes they lose to it. The details still reach the call record either way (a late post gets back-filled), so nothing looks broken, and that is the problem. Intermittent behavior nobody can reproduce is worse than either reliable answer. Set When to send to Before the call, or have your dialer post to their enrichment endpoint directly.

Pick the mechanism by what the receiving side needs to do with the data:

MechanismTelling or asking?When it sendsCan the destination refuse the call?
Data Delivery, On connectTellingAfter the destination answersNo. Reporting and CRM only
Data Delivery, Before the callTellingJust before each destination rings, with a 0.8 second head startNo. It is a heads up, not a question
Enrichment endpointTellingWhenever your dialer posts it, which should be before the transferNo, but their filters run on it if it lands in time
RTBAskingBefore the transfer, and we wait for the answerYes, plus a bid price and the number to dial

If the receiving side only needs to know who is calling, send the details before the transfer. If they need to decide whether to take the call and what to pay for it, use RTB: the bid request carries the caller's details and their answer comes back before the transfer happens, so the ordering is guaranteed rather than left to timing.


Where the data shows up

Open the call from the Calls page. The Pre-call data card shows your lead id and every field you sent, tied to that exact call, ready for reporting, reconciliation, or a dispute.


Limits to know

  • Matching needs the consumer's caller ID. If the transfer shows the dialer's own number instead, we can't match on the phone. Ask support about a dedicated number per lead.
  • You have 48 hours from sending the details to bridge the call, then the saved details expire.
  • The destination only gets the fields if you send them. The details always land on your call record. To pass them into the destination's own system, turn on Data Delivery or a Call Connected automation (see the step below).

FAQ

Frequently Asked Questions

Do I need a new API key or a different endpoint?
A new endpoint, /api/v1/calls/enrich, but the same API key your source already uses for this account. We always keep the caller's name, phone, and email; to store any extra fields, add them once in the campaign's Fields tab (after turning on Pre-call Data).
Can my dialer send a GET instead of a POST?
Yes. Send the fields as query parameters on a GET, or as a JSON body on a POST, whichever your dialer supports. Both work the same way.
What if the transfer can't pass the consumer's caller ID?
Email support@leaddistro.ai. We can set you up with a dedicated tracking number per lead so the match doesn't depend on the caller ID.
How long do I have to bridge the call after sending the details?
48 hours. In a warm transfer the call usually follows within seconds, so this is plenty of room.
Does my destination get the caller's details too?
Yes, if you set it up. Two ways: Data Delivery on the destination (Edit Target → Data Delivery) posts the caller's info to that destination's endpoint the moment they answer, and only to the one who actually took the call. Or a campaign-wide Call Connected automation, which can email the details to your client or post them to any URL. Without either, the details stay on your call record for your own reporting and disputes.
How is a passed versus an unqualified call billed?
Set the destination to bill when the call connects, so every passed transfer bills. If a transfer isn't qualified, refund that call and it shows as Returned.

If you have any questions, send us an email at support@leaddistro.ai