Skip to content
Guide12 min read · updated 2026-09-26By Stefan Köhn

How to Build a Lead Distribution System in 2026

Routing is the easy part. What decides whether a distribution system survives contact with real buyers is whether you can explain, months later, why a given lead went where it went.

Routing a lead to a buyer is a few lines of logic: check some conditions, pick a partner, send a webhook. If that were the whole job, nobody would sell software for it.

What makes a distribution system hard is everything around that decision. A buyer calls in October and says they were shorted in September. A partner insists a lead was a duplicate. A delivery came back 503 at two in the morning and nobody knows whether it ever arrived. None of those are routing problems, and all of them are the reason a spreadsheet stops working.

Build for the argument, not for the happy path. The single design decision that matters most is that every routing outcome has to be reconstructable months later: which partners were considered, which ones were skipped, and on which specific condition, cap or duplicate rule each one fell out. A system that records only what it did, and not what it declined to do, turns every dispute into your word against your buyer's.


When you have outgrown manual distribution

Any one of these is enough:

  • You forward leads by email. No delivery record, no caps, and the timestamp on the mail is the only evidence you have.
  • A spreadsheet answers "who got what". It is a second source of truth, and it disagrees with the first one within a month.
  • More than about five buyers, each with their own fields, caps and prices.
  • Buyers expect real-time delivery. In insurance, solar or home services, a lead delivered an hour late is worth a fraction of the same lead delivered in seconds.
  • You bill per lead. The moment money follows the delivery, the delivery needs an auditable record attached to it.

The six parts, and the decision inside each one

1. Ingestion

Leads arrive from web forms, from affiliate posts to your API, from file drops, or from ad platforms. The part people underestimate is the shape of the payload: Google Ads Lead Forms and Facebook Lead Ads post flat, one level of key and value, so an intake endpoint that insists on a nested object cannot accept them without a translation layer in front.

Decide up front whether validation happens at ingestion or at delivery. At ingestion is the right answer, because a lead that fails a required-field check should never enter the routing pool at all, and because the sender can still be told about it while the request is open.

2. Routing

Four models, and real setups combine them:

ModelWhat it doesFits
Rule and attribute basedRoute on state, postcode, lead type, amount, any fieldRegional or vertical buyers
Priority waterfallHighest priority first, next in line if the first is full or does not qualifyExclusive sales
BalancedThe qualifying partner who has received the least so far gets the next oneContractual volume splits
Send to allEvery qualifying partner gets the lead, up to a maximumShared or non-exclusive leads
A balance beats a round robin, and the reason is specific

Round robin is the obvious way to spread volume: keep a pointer, move it one partner to the right after each lead. It quietly fails, because the pointer advances even when the partner it landed on was skipped for a condition, a cap or a paused time window. Skip the same partner often enough and the month ends visibly lopsided, with nothing in the log saying why.

A balance asks a different question: of the partners who qualify right now, who has received the least this period? It self-corrects without a pointer, and a partner added mid-month starts at zero and catches up on its own. This is what our distribution module does, and it is the one place where the obvious design is the wrong one.

Order the checks from cheap to expensive. Active, then ancestor, then conditions, then time window, then caps, then duplicates. Conditions are arithmetic on data you already hold; caps cost a database query. A candidate that fails on a condition never needs to be counted, and on a busy account that ordering is the difference between a routing decision that takes milliseconds and one that takes a noticeable pause.

3. Caps

Four periods, and you need all four: day, week, month and total. Daily protects the buyer's ability to work the leads, monthly matches their budget, total covers a fixed-size test order.

The design detail that matters is what you show when one of them bites. If four caps are configured and the interface reports only the daily one, a partner reads "12 of 20 today", receives nothing, and spends an afternoon looking for a broken condition. Report the cap that actually stopped it, with its number, not the first one in the list.

Decide also whether you count gross or net. Counting deliveries gross, so that a lead still counts after it is returned, measures how you allocated. Counting net measures success and rewards a partner who returns a lot by putting them back at the front of the queue. Gross is usually right, and either way you should be able to say which one you chose.

4. Delivery

Two channels cover almost everything in practice: an HTTP post to the buyer's endpoint, and email for buyers with no system to post into. A portal where buyers log in is worth having, but it is not a delivery channel: it is how they review, export and return what was already delivered.

The hard part is failure, and it needs a written policy rather than a retry loop:

  • Distinguish "later" from "wrong." A timeout, a 429 or any 5xx is later. A 4xx other than 429 is wrong, and waiting does not make a bad endpoint or a rejected payload correct.
  • Bound the retries and back off. Three attempts at five, fifteen and sixty minutes is a reasonable shape. Unbounded retries turn one broken buyer into a queue that never drains.
  • Send an idempotency key on every attempt, and put it in the payload too. Without it, a retry after a timeout that actually succeeded leaves the lead in the buyer's system twice, and then two companies argue about whether it is payable twice.
  • Decide what "delivered" means with several channels on. The defensible answer is all of them or none: mark it delivered only when every enabled channel got through, and record which one failed when it did not.
One delivery
every attempt, with its answer
Rheinwerk Süd GmbHWebhookdelivered120,00 €
  1. 09:14:02504no answer, retry in 5 minutes
  2. 09:19:02504no answer, retry in 15 minutes
  3. 09:34:02200accepted

Idempotency-Key: 8f3a…c210

5. Deduplication

Two decisions, and they are independent.

What makes two leads the same. Pick the fields, normalise them: trim, lowercase, reduce phone numbers to digits. Then pick a window, thirty days being the common default. Store a hash of that fingerprint rather than the values themselves. If you keep name@example.com|447700900000 next to every distribution for three years, your duplicate check has quietly become a second database of personal data with its own retention obligation, and it answers no question that the hash does not.

What a duplicate means. At record level, the lead was here before and is not distributed at all. At partner level, only that partner drops out and the lead carries on down the waterfall. The second is the more useful one and it is the one people forget to build: that partner A already had this person last month is no reason for partner B to get nothing.

One more case worth handling explicitly: if all the fingerprint fields are empty, that is no check, not a duplicate. Otherwise the first lead with no email blocks every later lead with no email.

6. Revenue and the paper trail

Every delivery carries a price, and two pricing shapes cover most agreements: a fixed amount per lead, or a rate multiplied by a field on the lead, which is how you price by loan amount, system size or contract value. Volume-tiered pricing sounds obvious and is a good deal more work, because a mid-month tier change reprices deliveries that already happened.

Then, separately from routing, the run at the end of the month that turns deliveries into documents. If you invoice inside the EU that means gapless numbering, the correct tax case including reverse charge, credit notes for returned leads, and a machine-readable format your buyer's accounting system accepts. This is where most home-built systems stop and a spreadsheet takes over permanently.


The rehearsal is the feature nobody asks for

Every dispute is the same question: why did this lead go there? A system that can answer it before delivery can also answer it afterwards, because it is the same answer.

Dry run
Runs a real record through rule by rule. Sends nothing, writes nothing.
Record 4812Rooftop DE · highest price2 partners get it
Nordkontor Vertrieb GmbH€38.00
Rheinwerk Süd GmbH—
Vialux Solar B.V.—
Alpsol Handels GmbH—
Cetus Partner GmbH€38.00
The same function the real run uses, without the write path. Nothing was sent.
Invoice 2026-0418Paid
62 leads · Nordkontor€2,356.00
Reverse charge€0.00
ZUGFeRD sent
Credit note 2026-0419Open

2 leads returned inside the deadline, credited at −€76.00. The paid invoice stays paid.

Take a real lead, run the selection, and show every partner that was considered together with the verdict on each: chosen, or skipped and on exactly which condition, cap, window or duplicate rule. The version of this that only prints the winner is much easier to build and worth far less, because the question people actually ask is about the partners who did not get it.

It also changes what happens when you edit a rule. Without a rehearsal, you change a condition and find out from a buyer next week.


Building it yourself, honestly

Building is the right call in one situation: you have a routing model no platform supports, you have engineers, and distribution is close enough to your core business to deserve them. That is a real scenario and it is not rare.

What you are committing to, based on the list above:

You will buildNot optional because
Rule evaluation over arbitrary fieldsEvery buyer wants a field you did not anticipate
Four cap periods with correct reportingA wrong cap message costs a support afternoon each time
Fingerprints, hashing, windows, two levelsDuplicates are the most common dispute
A delivery queue with backoff, retry classes and idempotencyBuyers' endpoints go down, and yours has to not double-post
A decision log with reasons for rejectionsThis is the one you will wish you had built first
Statutory invoicing, if you are in the EUIt is the law, not a preference

Three to six months is the usual honest estimate for a first version, and the decision log and the invoicing are the two parts that get deferred and then cost the most.


How Leadflip does it

Ours, so treat this module as a worked example rather than a recommendation.

Each buyer participates through a rule that carries its own conditions over any field on the record, its four caps, its price, its delivery channels and its time window in the partner's own timezone, because the callback happens where the partner is and not where your account is. A window can be left empty, which means always open, and calendar blocks can be a one-off date or a yearly recurrence.

When a lead falls outside a partner's window you choose what happens: skip, and the lead continues to the next partner, or hold, and it waits for the next opening. Holding carries a condition that is the reason it is not the default: a held lead must not silently expire, so the system computes the time it will resume and shows it.

Selection returns one verdict per rule in evaluation order, including the rejected ones with their reason, and that same structure is both the rehearsal and the permanent log. Distribution results also land on the record's timeline in the CRM, which matters mainly because the lead you routed and the lead your own team works are the same record rather than two copies.

What we do not have, so you do not find out later: no ping/post or auctions, which is a decision rather than a gap; no call routing; two delivery channels rather than five, and no scheduled file delivery; and no CSV import, so a file drop needs to go through the intake API. That endpoint accepts flat payloads deliberately, which is why Google Ads Lead Forms and Facebook Lead Ads work today without a translation layer.

For the parts we are missing, the platform roundup says plainly who has them. Checked on 26 September 2026: LeadByte publishes scheduled file delivery and Facebook Lead Ads capture, boberdoo and Lead Prosper publish ping/post at scale.



How this page was written

The engineering claims about our own product are read off the distribution module rather than from a feature list, which is why this version names three delivery retries at five, fifteen and sixty minutes and two delivery channels instead of "automatic retry logic" and three channels. The earlier version of this page also listed CSV upload as an ingestion route and volume-tiered pricing as available. Neither exists here, and both have been removed rather than softened.

Competitor capabilities were read on 26 September 2026 on those vendors' own pages. Where a capability is missing from our side, this page names it and points at who has it.

If something here is out of date or wrong, tell us and we will correct it.

Bring the month you would rather not talk about

Set up your own entity, your own fields and one routing rule, and see what it does with a record you put through it.