Part 2 of our Affiliate Mastery Series. Part 1 covered vetting. Now we track.
If you can’t see which traffic source, which landing page, and which offer produced each conversion — you are flying blind. You can’t scale what’s working, kill what isn’t, or detect shaving when it happens. Tracking is the foundation of every profitable adult affiliate business.
This post is the full 2026 tracking stack: subIDs, postbacks, pixels, how they fit together, and how to debug when they don’t.
The Three Layers of Affiliate Tracking
Layer 1: Click Tracking
Who clicked which link, from where, when. You control this at your end via click.php (or equivalent) that logs the click before redirecting to the affiliate URL.
Layer 2: SubID Passing
You tag each click with identifiers (subID, source, creative, placement) in the outgoing URL. The affiliate network echoes these back on conversion.
Layer 3: Conversion Postback
When a user converts on the advertiser’s side, the network fires a server-to-server call to your tracker, including those subIDs, telling you exactly which click converted.
All three together = end-to-end attribution. Missing any one = partial blindness.
Understanding SubIDs: The Backbone of Attribution
Nearly every adult affiliate program supports 3–5 subID slots (s1–s5, sub1–sub5, or aff_sub–aff_sub5). They’re arbitrary strings you pass in the click URL. The network stores them, and returns them on any conversion.
Recommended SubID Convention
- s1 = click_id (unique UUID per click; lets you join back to your own logs)
- s2 = source (e.g., “organic”, “exoclick-popunder-5512”, “newsletter-0427”)
- s3 = creative/banner ID
- s4 = landing page variant
- s5 = geo / misc
Sample Outgoing URL
https://affiliate.example.com/offer?a=12345&s1=a7b8c9&s2=exo-popunder-5512&s3=banner-milf-v2&s4=lp-longform&s5=US
S2S Postback: What It Is and Why It Matters
A server-to-server postback is a URL the affiliate network calls on conversion. It doesn’t require the user’s browser to be involved. That’s critical in 2026 because:
- Cookies are unreliable (ITP, Firefox, privacy extensions).
- Pixels are blocked by ad-blockers and tracker blockers.
- Users convert in-app, via email, or weeks after the original click.
S2S bypasses all of that. The network’s server talks directly to your server.
Sample Postback URL Format
https://yourdomain.com/ct/api/v1/postback?click_id={s1}&offer_id={offer_id}&payout={payout}&event={event_name}&status={status}
The {variable} tokens are macros the network replaces at fire time.
What Your Endpoint Must Do
- Validate the IP (optional but recommended — networks publish their IPs).
- Look up the click_id from your clicks table.
- Log the conversion with payout, event type, timestamp.
- Return HTTP 200 quickly (within 2 seconds). Networks retry on timeout or 5xx.
- Handle duplicates (networks sometimes fire twice).
Event Types You Should Track Separately
- reg — Free registration.
- first_deposit — First money spent (PPS event).
- rebill — Subsequent recurring payments.
- chargeback — Reversed sale.
- refund — Merchant-initiated reversal.
- upsell — Post-purchase add-on.
Most networks fire all of these through the same postback endpoint with an event-name field. Log every event, even zero-value ones — they’re critical for diagnosing drop-off.
Building a Minimum Viable Tracker (In-House)
You don’t need Voluum or BeMob to start. A 100-line PHP + MySQL setup will get you 90% of the value:
Database Schema
tblClicks click_id (uuid, primary key) source, campaign, creative, lp_variant, geo, device referrer, user_agent, ip, country clicked_at, redirect_url tblConversions conversion_id, click_id (fk), network, offer_id event_type, payout_usd, status (confirmed|pending|rejected|chargeback) postback_received_at, raw_payload
Core Flow
- User clicks your CTA → hits
click.php. - Generate UUID, log click row, redirect with
s1=[uuid]. - User converts at advertiser.
- Network fires postback to
/postback?click_id=[uuid]&payout=30. - Your endpoint logs the conversion and updates aggregate stats.
Build this once and every network with S2S support will Just Work.
Third-Party Trackers Worth Considering
| Tracker | Type | Adult-Friendly | Pricing |
|---|---|---|---|
| Voluum | Cloud | Yes | $149+/mo |
| BeMob | Cloud | Yes | Freemium |
| RedTrack | Cloud | Yes | $83+/mo |
| PeerClick | Cloud | Yes, built for adult | $49+/mo |
| Binom | Self-hosted | Yes | $99/mo license |
| FunnelFlux Pro | Self-hosted | Yes | $99+/mo |
Self-hosted (Binom, FunnelFlux) wins on speed and cost once you exceed ~1M clicks/month. Cloud is fine for most.
Spotting Shaving: Three Diagnostic Patterns
Pattern 1: EPC Divergence Between SubIDs
Two campaigns sending visually identical traffic to the same offer. Campaign A: $0.42 EPC. Campaign B: $0.08 EPC. If you’ve ruled out quality differences, the network is scrubbing Campaign B.
Pattern 2: Conversion Time Lag Jumps
Normal conversion timing is predictable (e.g., 70% within 30 minutes of click for impulse offers). Suddenly your conversion timestamps cluster at “exactly 48 hours after click.” That’s an artificial attribution window — the network is silently shortening the credit window.
Pattern 3: Own-Logs vs. Dashboard Mismatch
Your postbacks logged 137 conversions yesterday. Today the dashboard reports 122. Fifteen quietly vanished. If this is >5% of volume, it’s systematic.
Tracking Hygiene: Five Rules
- Always pass s1 as a unique click ID. This is your link back to your own data.
- Never trust dashboard totals alone. Compare postback-received count vs. dashboard daily.
- Use HTTPS on your postback endpoint. Some networks refuse HTTP in 2026.
- Handle retries idempotently. Same click_id + same event = update, not duplicate row.
- Back up click logs. If your VPS dies, so does your history — and with it any dispute evidence.
Coming Up in Part 3
Now you’ve got clean data. Time to use it for negotiation. Part 3: how to negotiate custom deals — when to ask for a rate bump, what leverage actually works, how to get white-label offers, and the email scripts that get AMs responding.