How to set up end-to-end analytics: S2S postbacks in Keitaro and Binom
When the tracker pulls numbers only from the landing page or call tracking, a dead zone opens up between the click and the conversion, and the real CPL, CPC, and ROI by creative and source disappear into it. An S2S postback (server-to-server) sends the conversion event from the advertiser's or network's server straight to the tracker, bypassing the browser, and recovers those numbers - whether the tracker is Keitaro or Binom.

What you need before you start
Before touching postbacks, three things need to be in place: a tracker (Keitaro or Binom, already installed and taking traffic), an ad account - TikTok Ads, Meta, Google Ads, whichever is running the spend - and an offer that supports postbacks. Working through a CPA network means asking the manager for the postback link, usually a URL carrying macros like {clickid}.
Keitaro asks for an API token and a flow (offer) ID; Binom wants a campaign ID and an auth token; both accept postbacks as a GET request. If the offer doesn't support S2S, a pixel postback is the fallback - and it's less reliable, since ad blockers can stop it from firing at all.
The tracker has to pass a unique click identifier (clickid) into the offer link correctly, or the postback won't tie back to its source. Check that the offer link carries the {subid} macro for Keitaro or {clickid} for Binom.
- Admin access to the tracker
- An ad account with an active campaign
- An offer that supports S2S postbacks, or at least a CPA link with macros
- A Keitaro API token or a Binom token
Create a flow (offer) in Keitaro
A new flow gets created in the 'Offers' section. The 'Destination URL' field takes the offer link with the {subid} macro in whichever parameter the network expects for its postback - for most networks that's subid={subid} or click_id={subid}. If the network uses a different parameter, aff_sub say, it's worth confirming with the manager.
In the flow settings, check the 'Accept postbacks' box - that lets Keitaro take postbacks from outside systems. If the offer only supports a pixel postback, Keitaro will generate a pixel URL, but S2S is more reliable, and that's the one worth setting up.
Once the flow is saved, Keitaro will display a unique postback URL - something like https://your-tracker.com/postback?subid={subid}&payout={payout}. Copy it - the network or the advertiser will need it on their end.
Setting conversion statuses
Keitaro recognizes three conversion types - sale, lead, reject - and one has to be chosen to pass to the tracker. 'Sale' is the usual choice for confirmed leads. Holds (pending) from the network are better left out of the conversion count, or ROI ends up inflated.
Set up the postback in Binom
In Binom, open 'Campaigns', then the campaign, then 'Edit campaign.' The 'Postback URL' field takes the link Binom generated for that campaign - usually something like https://your-binom.com/postback?clickid={clickid}&payout={payout}&status={status}.
The {clickid} macro has to match what's passed in the offer link - Binom carries the click identifier through {clickid} specifically. In the campaign settings, in the 'Offer URL' field, {clickid} needs to sit exactly where the network expects click_id.
Binom works with three conversion statuses: 1 (approved), 0 (pending), -1 (rejected). If the network sends status in a different format, a small PHP converter script becomes unavoidable, though in practice, approved is usually all that gets used.
Setting up conversion notifications
Binom can send an email notification for every conversion - handy early on, just to confirm the postback works at all. Past 100 conversions a day, the notifications are worth switching off, or the inbox drowns.
Integrating with the affiliate network or advertiser
The postback URL then goes to the network - inside its dashboard, that's the 'Postback' or 'Callback URL' section. The copied URL from Keitaro or Binom goes in there, with {clickid} swapped for the network's own macro: in most cases that's also {clickid}, but {sub_id}, {aff_sub}, and {transaction_id} show up too - check the network's documentation for the exact one.
At the CPA network KMA.biz, for instance, the postback link looks like this: https://your-tracker.com/postback?clickid={clickid}&payout={payout}, and in the network's settings, {clickid} gets marked as the parameter the network will fill with the real click identifier.
After saving, it's worth running a test pass: click through the ad link and complete the target action - a registration, a purchase. If the postback is set up correctly, the tracker will show a conversion with its traffic source attached.
Checking the postback: catching errors
The tracker logs come first: in Keitaro, open 'Logs', then 'Postback logs'; in Binom, 'Logs', then 'Callback logs.' The response status reads plainly: 200 means success, 404 means the URL wasn't found, 500 means a server error.
A 200 status with no conversion showing in the tracker is almost always a clickid mapping problem: the click identifier coming from the network has to match what the tracker already holds. The usual culprit is {clickid} sitting in the offer link while the network is actually sending {subid}.
A postback delayed more than 30 seconds can just get rejected by the tracker - the fix is raising the timeout in settings: up to 60 seconds in Keitaro, 120 in Binom.
- Status 200 means the postback arrived.
- Status 404 means the postback URL is wrong.
- Status 500 indicates an error on the tracker's or network's side.
- A conversion visible in the logs but missing from the stats means the clickid mapping is wrong.
Setting up payout transmission
For the tracker to calculate ROI, the {payout} macro gets added to the postback URL - the network needs to support it and pass the actual payout amount for the conversion. If the network doesn't send payout, a fixed amount can be set instead, in the flow settings (Keitaro) or the campaign settings (Binom).
It looks like https://your-tracker.com/postback?clickid={clickid}&payout={payout}, with the network's settings marking {payout} to be replaced by the conversion amount. If the network doesn't support that, set it to 0 and work out ROI by hand in Excel - unwieldy over time, at which point switching networks makes more sense.
For offers with different payouts - registration at $2, deposit at $10, say - different conversion statuses or different postback links get used: in Keitaro, that means setting up several flows for one offer; in Binom, it's handled with multi-postbacks.
Integrating with ad accounts (TikTok, Meta, Google)
Running traffic straight to the offer, with no network in between, means sending the conversion to the ad platform yourself. Meta takes server-side events through its Conversions API rather than a plain postback URL, and the click identifier it puts in the landing page URL is fbclid - store that on the click and send it back with the event.
TikTok works the same way through its own Events API, and its click identifier in the landing page URL is ttclid. Store it on the click, pass it back with the conversion, and the platform matches the two. Both platforms move these screens around, so the current click path belongs in their own documentation.
Google Ads works through Google Tag Manager or the site's global tag - GTM can send the event straight to the tracker's server. A plain postback is enough to get started; budget allowing, a third-party connector like Hyros or Triple Whale makes the job easier.
Missing clickid, mismatched statuses and duplicate conversions
- Clickid never gets passed. The offer link is missing {subid} (Keitaro) or {clickid} (Binom), so the tracker gets no identifier and the postback doesn't attach to anything. The usual cause is a beginner copying the link straight from the network and forgetting to append clickid.
- Mismatched statuses. The network sends 'approved,' the tracker is waiting for 'sale.' Keitaro fixes this with status mapping in the 'Conversion types' section; Binom needs a small handler script instead.
- The postback goes to the wrong URL. When the tracker's address gets confused with the landing page's, the fix is straightforward - the destination is only the tracker's server, never the offer page, and the domain in the logs shows which one actually received the request.
- Duplicate conversions. The network sends the same postback more than once, say on a repeat visit, and the tracker counts each one separately. Deduplication by clickid fixes it - a checkbox in the flow settings for Keitaro, off by default in Binom and switched on in the config.
What you get: real numbers and metrics
Once the postbacks are set up, the tracker shows CPL for every creative and source, split by platform and geo - numbers no ad account dashboard breaks out on its own.
ROI turns transparent after that. With a $50 payout per lead and a $20 CPL, ROI = (50-20)/20 = 150%. Without postbacks, only CPC is visible; profit by source isn't.
Optimization speeds up too - unprofitable creatives with CPL above the break-even line get switched off within an hour of launch.
FAQ
Why doesn't the postback show up when the logs say status 200?
Most likely the clickid doesn't match: the offer link needs the same macro the network expects - {subid} in Keitaro, {clickid} in Binom. If the network uses a different parameter, aff_sub say, it's worth requesting its documentation.
Can one postback serve several offers?
In Keitaro, yes: one flow with a postback takes conversions from every click routed to it. In Binom, the postback is tied to the campaign, so each offer gets its own campaign, or {clickid} gets used with different prefixes.
How do you confirm a postback works without a test conversion?
Services like webhook.site help: the postback URL goes in as the endpoint, and a GET request with clickid=test123 gets sent manually. If the tracker accepted it, a conversion marked type 'test' shows up in the logs. Binom also has a built-in 'Test postback' function in the campaign settings.
How long does setting up S2S postbacks take?
The first time, 30-60 minutes, with the network's documentation on hand. After that, a new offer takes 10-15 minutes. If the network doesn't provide macros, a proxy script has to be written, and that's a day's work.
I can do this on your product
I consult on acquisition, funnels and retention - including hard verticals.
