Revenue share vs CPA: the math behind the choice
Most affiliates pick a payout model out of habit. Here is the arithmetic that should decide it: retention thresholds, cohort curves, capital velocity and the risks on both sides.
Read postA practical guide to S2S postback tracking for affiliates: click IDs, postback URLs, testing, deduplication, and fixing conversions your tracker never received.
You send 40,000 clicks in a month. Your tracker shows 312 conversions. The advertiser's panel shows 341. Nobody is lying, and nobody is stealing from you — somewhere in the chain, 29 conversions lost the thread that connects them back to a click. That gap is worth real money, and it is almost always a fixable configuration problem rather than a mystery.
S2S postback tracking is the mechanism that keeps that thread intact. It replaces the fragile browser-side pixel with a direct server-to-server call, and once you understand what is actually moving between the two machines, most conversion discrepancies stop being spooky and start being debuggable.
This guide walks the whole path: what a click ID is and where it can get dropped, how to read a postback URL parameter by parameter, why pixels degrade while postbacks do not, how deduplication works, how to test the whole loop before you spend a cent, and what to check when two dashboards disagree.
Strip away the jargon and a postback is an HTTP GET request. The advertiser's server calls a URL on your tracker's server. That URL contains a value — the click ID — that your tracker handed to the advertiser at click time. Your tracker looks up that click ID in its own database, finds the original click with all its attached metadata, and marks it converted.
That is the whole idea. Two servers, one shared identifier, no browser in the middle.
The reason this matters is that the browser is the least reliable participant in the funnel. It can be an in-app webview with no persistent storage. It can block third-party cookies by default. It can have an extension that kills the tracking script. The advertiser's server, by contrast, will happily make an outbound HTTP request every single time, because nothing in the user's environment can reach it.
You will see the same concept called a postback, a server-to-server callback, S2S tracking, or a conversion callback. Some platforms call the click ID a clickid, others transaction_id, aff_sub, subid, sid, or cid. Do not assume the naming carries meaning — read the advertiser's integration doc and match their field names exactly. Half the broken setups I have unpicked were caused by an affiliate passing clickid to a platform that reads transaction_id.
Everything else in postback tracking is decoration. If the click ID survives the round trip, you get paid correctly. If it does not, nothing else you configure matters.
Your tracker generates the click ID at the moment of the click. It is a unique string — typically a UUID or a hashed sequence — created before the redirect fires. At that instant your tracker writes a row containing the click ID plus every dimension it knows: timestamp, IP, user agent, geo, device, offer, and all your sub-IDs. That row sits waiting.
The click ID then travels outward in the redirect URL. It rides through the advertiser's landing page, through their registration flow, into their internal user record, and eventually back to you inside the postback. The longer that journey, the more places it can get lost.
ClickID is not clickid on most systems. And if your click ID contains characters that need URL encoding, an unencoded pass can truncate it.A typical postback URL you would hand to an advertiser looks something like this:
https://track.yourdomain.com/postback?cid={clickid}&payout={payout}¤cy={currency}&status={status}&txid={transaction_id}&goal={goal_id}
The curly braces are macros. The advertiser replaces them with real values when they fire the call.
| Parameter | What it carries | Why you want it |
|---|---|---|
cid / clickid |
The unique click identifier you generated | The join key. Without it nothing matches. |
payout |
The commission amount for this conversion | Lets your tracker calculate real ROI per sub-ID instead of assuming a flat payout. |
currency |
ISO code such as USD or EUR | Prevents a EUR payout being counted as USD, which quietly inflates your reported profit. |
status |
approved, pending, rejected, chargeback | Enables lifecycle handling rather than treating every fire as final revenue. |
txid |
The advertiser's own unique transaction reference | The deduplication key. Covered below. |
goal |
Which event fired: registration, deposit, qualification | Essential for any funnel with more than one payable event. |
Not every advertiser supports every macro. Ask for their macro list rather than guessing, because a macro that does not exist on their side is usually passed through as the literal string {payout}, and your tracker will either reject it or record a payout of zero.
If you accept a static payout in your tracker instead of a dynamic {payout} macro, every conversion gets recorded at your assumed rate. On a fixed CPA that is fine. On a tiered deal, a hybrid, or anything revshare-flavoured, it is fiction. You will optimise toward placements that look profitable because the tracker assumed a payout they never actually earned. If you are comparing offers on earnings per click and the other core metrics, a static payout assumption corrupts every one of them at the source.
Walking this end to end makes the failure points obvious.
Note step 5. Once the click ID is bound to a user account on the advertiser's server, browser restrictions become completely irrelevant. A conversion that happens three weeks later on a different device still fires correctly. That durability is the real argument for S2S postback tracking, and it is why offers with long consideration cycles — high-ticket funnels especially — are effectively untrackable any other way.
A conversion pixel is an image or script tag on the advertiser's confirmation page. It fires in the user's browser, and it identifies the click by reading a cookie your tracking domain set earlier. Every one of those dependencies is now under pressure.
Cookie lifetime restrictions. Browsers have progressively shortened how long script-set cookies survive, in some configurations to a matter of days or even a single day. Any conversion with a delay longer than that window is invisible to a pixel. Deposit journeys in finance and iGaming routinely run longer than that.
Third-party context. A cookie set by your tracking domain while the user is browsing the advertiser's domain is a cross-site cookie. Default blocking of those is now normal rather than exotic.
In-app browsers. A large share of paid social and messenger traffic never touches a real browser. It opens in an embedded webview inside the app. Those webviews often have isolated or ephemeral storage, so a cookie set at click time may not exist at conversion time even seconds later. If most of your volume is Telegram or messenger traffic, pixel-based tracking will understate you badly.
Ad blockers and script failures. Blockers commonly filter known tracking domains. A pixel that never loads is a conversion that never existed as far as you are concerned.
Page-load dependency. If the user closes the confirmation page before the pixel executes, or the advertiser fires the conversion in a JavaScript modal that a slow connection never renders, the pixel silently does not fire.
A postback bypasses all five. The advertiser's backend calls your server directly, carrying the click ID as an explicit parameter. There is no cookie to expire, no script to block, no page to load.
The honest caveat: postbacks are only as good as the advertiser's implementation. If their server has a bug, queues calls and drops them under load, or fires only on a subset of events, you lose conversions in a way you cannot see from your side. Which is why testing is not optional.
Postbacks get fired twice more often than you would expect. Retry logic after a timeout, a manual conversion re-push by an account manager, a status change from pending to approved implemented as a second fire rather than an update — all of these produce a repeat call.
If your tracker counts both, your reported revenue inflates and your optimisation decisions get built on phantom conversions. The fix is the advertiser's transaction ID. Store it against the conversion, and reject any incoming postback whose transaction ID you already have for that click.
Deduplicating on click ID alone is the wrong instinct, because some funnels legitimately produce multiple conversions from one click: a registration, then a first deposit, then a second deposit under a revshare arrangement. Deduplicate on the pair — click ID plus transaction ID, or click ID plus goal plus transaction ID for multi-event setups.
Set a sensible window too. If the same transaction ID arrives 40 days later it is far more likely to be a system replay than a genuine event.
Do this every time you take on a new offer. It takes ten minutes and it has caught broken setups on plenty of offers that were supposedly live and working for other affiliates.
Then delete the test conversions so they do not pollute your baseline.
Postback registered against the wrong event. You are paid on qualified deposit but the postback fires on registration. Your volume looks fantastic and your revenue does not match it.
Whitelisting that blocks the caller. If your tracker sits behind a firewall or WAF that filters unknown server IPs, the advertiser's calls get rejected before your tracker sees them. Nothing appears in your logs, because nothing reached your logs. Check the edge, not just the application.
HTTP versus HTTPS mismatch. Some advertisers refuse to call insecure endpoints; some fail silently on certificate errors. An expired certificate on your tracking domain kills every postback until you renew it, and the failure mode is total silence.
Redirects on the postback endpoint. If your postback URL 301s to a canonical version, some callers follow it and some do not. Give them the final URL.
Currency assumptions. An advertiser paying in EUR while your tracker assumes USD will overstate your revenue by whatever the exchange rate difference happens to be. Small per conversion. Substantial at volume.
Ignoring status. If you count pending conversions as approved, your reported profit runs ahead of reality and corrects downward later, usually right when you have already scaled spend on the strength of it.
Rate limiting. A tracker that rate limits by IP will start dropping calls during a traffic spike, which is exactly when you can least afford it.
Run the arithmetic, because "a few percent" sounds tolerable until you price it.
You are running a CPA offer at $180. In a month you drive 40,000 clicks at $0.22 CPC, so $8,800 in media spend. Your tracker records 312 conversions.
The advertiser's panel shows 341 conversions. The 29 missing ones are worth 29 × $180 = $5,220. Assuming the advertiser pays on their own count, you are not losing that cash — you are losing the information.
That matters because the missing conversions are not randomly distributed. Suppose 21 of them came from one placement, an in-app messenger source that sent 6,400 clicks and cost $1,408.
Your tracker reported an EPC of $0.51 on that source. The real EPC was $1.10. You would rank it mid-table and cap its budget, when it was your best source by a wide margin. The 29 lost conversions cost you nothing directly and cost you a great deal in misallocated spend — which is precisely why per-source verification matters more than the headline total. This is the same discipline that makes sub-ID reporting useful in the first place.
Single-event offers are easy. Most serious verticals are not single-event.
A typical iGaming or broker funnel has a registration, a first-time deposit, and sometimes a qualification threshold — a minimum deposit, a volume requirement, or a KYC completion. Each of those should fire its own postback with a distinct goal value.
Configure them as separate goals in your tracker rather than one lumped conversion. The reason is diagnostic: registration-to-deposit ratio is one of the most informative numbers you have. A source producing plenty of registrations and almost no deposits is usually low-intent traffic or a geo mismatch, and you cannot see that if every event collapses into a single counter.
Watch the status lifecycle too. Deposits reverse. Chargebacks arrive weeks later. If your advertiser sends a status-update postback for a reversal, handle it — a conversion that flipped to rejected should stop counting as revenue, and if you are on a revshare deal with negative carryover, that reversal has consequences beyond a single row in a report.
Some discrepancy is normal. Timezone boundaries alone will make any single day's figures differ. What you are hunting is a persistent, one-directional gap.
Work through it in this order:
Bring evidence to your manager, not vibes. Timestamps, click IDs, and response codes get a fix in a day. A message saying your numbers look low gets you a shrug.
Tracking infrastructure is one of the things we build and maintain for our partners rather than leaving to you. That means postbacks configured and tested against each advertiser before traffic runs, sub-IDs verified end to end, and discrepancies chased directly with the platform rather than through a support queue. We also build the sites and landing pages, which removes the most common click ID failure point — a pre-lander that quietly drops your query string.
Our partners run on a 50% revenue share across crypto, forex, iGaming, gaming, high-ticket and tech, with direct platform relationships that make it possible to get raw postback logs from an advertiser when something looks off. If you would rather spend your time on traffic than on debugging why 29 conversions went missing, start on our Telegram bot or come ask questions in the community chat first.
S2S postback tracking is a server-to-server method of recording conversions. When a user clicks your link, your tracker generates a unique click ID and passes it to the advertiser. If that user converts, the advertiser's server calls a postback URL on your tracker with the same click ID attached, and your tracker matches it back to the original click. No browser, cookie, or pixel is involved.
In almost every case, yes. A pixel fires in the user's browser and depends on cookies, JavaScript execution, and the page actually loading. Cookie lifetime limits, ad blockers, in-app browsers, and cross-site restrictions all break pixels. A postback is a direct server call that carries the click ID as a parameter, so none of those conditions affect it.
The usual cause is a lost click ID. Check whether your landing page strips URL parameters on redirect, whether the advertiser's signup form preserves the click ID across steps, and whether you are passing the parameter name the advertiser actually expects. Also confirm the postback is configured for the correct event and that your tracker is not rejecting duplicates.
At minimum the click ID and a status or event type. Most setups also pass payout amount, currency, the advertiser's own transaction ID for deduplication, and the offer or goal identifier for multi-event funnels. Anything else, such as geo or device, is usually already stored against the click on your side and does not need repeating.
Most affiliates pick a payout model out of habit. Here is the arithmetic that should decide it: retention thresholds, cohort curves, capital velocity and the risks on both sides.
Read postExchanges still pay the best lifetime economics online, but the traffic that earns them changed. What converts now, what quietly died, and how to price a program before you send traffic.
Read postThe gap between a 2% and an 8% click-to-registration rate is almost never the casino. It is the funnel. Here is the full chain, the arithmetic behind each step, and how to find the leak.
Read post