How to Track Affiliate Conversions with Short Links (Postbacks & Pixels)
Step-by-step guide to tracking affiliate conversions with ShortlyLink — click IDs, server-to-server postbacks, thank-you-page pixels, HMAC signing, dedup, and payout caps.
Tracking affiliate conversions comes down to one thing: proving that a click on your short link turned into a paid action, without double counting and without trusting numbers you can't verify. ShortlyLink does this by signing every redirect with a click id and an HMAC-SHA256 signature, then accepting conversions back through two channels — a server-to-server postback or a browser pixel — that both flow through the same signed, deduplicated path. This guide walks the full setup, step by step, so your revenue dashboard reflects real, attributable payouts.
Quick answer
- Create a tracked short link and set a
maxPayoutup front so no single conversion can report an absurd amount. - On redirect, ShortlyLink appends a click id (
cid), an expiry (exp), and a signature (sig) to your destination URL. Your network must return these on conversion. - Fire a server-to-server postback (
GET /postback) when your affiliate network supports it, or drop a thank-you-page pixel (POST /api/conversions/pixel) when it doesn't. - Conversions are validated against the 24-hour signature, deduplicated by click id (a repeat is HTTP 409), clamped to your payout cap, and normalized to confirmed / pending / rejected.
- Watch results in the revenue dashboard, export to CSV, and optionally push a conversion webhook to your own systems.
Step 1: Create a tracked short link and set a max payout
Start by creating the short link you'll place in your campaign. Point it at your affiliate offer URL (your destination), and while you're setting it up, set the link's maxPayout.
The max payout is a safety cap. Affiliate networks occasionally misfire, send test data, or report a currency in the wrong unit — and without a ceiling, a single bad postback could report a $10,000 sale that never happened. When you set maxPayout, any conversion amount above it is clamped down to that ceiling before it ever touches your revenue totals. If you don't set one, ShortlyLink applies a default max of 1000. Set it deliberately to match your realistic per-conversion payout.
This is the number-one habit for affiliate marketers on ShortlyLink: cap the payout at link creation time, not after you've already ingested garbage. See the features page for the full link-management surface, including scheduling, parameter forwarding, and branded domains.
Step 2: Understand what ShortlyLink appends on redirect
When someone clicks your short link, the redirect is an HTTP 302 to your destination — but ShortlyLink doesn't send them to a bare URL. It appends three query parameters that make the conversion verifiable later:
cid— the click id. This is the unique identifier for that specific click. It's what ties a later conversion back to the exact click that produced it.exp— an expiry timestamp. The signature is only valid for a limited window (see Step 4).sig— an HMAC-SHA256 signature computed over the click id and expiry using a secret only ShortlyLink holds. This is what makes the values tamper-evident. A conversion can't be forged by guessing a click id, because the attacker can't produce a matching signature.
So your affiliate offer receives a destination like https://offer.example.com/?cid=<16-char id>&exp=<timestamp>&sig=<hmac>. Your job in the next steps is to make sure those three values survive the round trip and come back to ShortlyLink when the conversion fires.
Two practical notes. First, ShortlyLink's per-link parameter forwarding controls whether the visitor's own query params pass through, but the cid/exp/sig trio is what conversion tracking depends on — preserve them through any redirect chain on your side. Second, the forwarded URL is capped at roughly 2,048 characters, so keep destination URLs lean.
Step 3: Choose postback vs. pixel
There are two ways to report a conversion back to ShortlyLink. Both end up on the same signed, deduplicated path — the difference is who calls it and when.
- Server-to-server postback —
GET /postback. Your affiliate network's servers call this endpoint directly when a conversion is confirmed on their side. You configure the postback URL inside the network's dashboard, using their macros to fill in the click id, amount, and status. Because it's server-to-server, it doesn't depend on the buyer's browser, ad blockers, or whether the thank-you page actually loaded. This is the more reliable option and the one to prefer whenever your network supports postback (also called S2S or server postback) URLs. - Thank-you-page pixel —
POST /api/conversions/pixel. When a network can't fire a postback, you drop a small pixel on the order-confirmation ("thank you") page. When the page loads after a purchase, the pixel posts the click id and amount back. This works without network cooperation, but it's browser-dependent: blockers, redirects that drop params, and users who never reach the thank-you page can all cost you conversions.
Postback vs. pixel at a glance
| Server-to-server postback | Thank-you-page pixel | |
|---|---|---|
| Endpoint | GET /postback |
POST /api/conversions/pixel |
| Who calls it | The affiliate network's servers | The buyer's browser |
| Trigger | Network confirms the conversion | Thank-you page loads |
| Reliability | High — no browser dependency | Lower — blockers, dropped params, page not reached |
| Setup | Paste a postback URL with the network's macros | Embed a pixel snippet on the confirmation page |
| Best when | The network supports S2S postbacks | You control the landing page but not the network |
New to the concept? Read what is a postback URL for a plain-English breakdown, then come back here to wire it up.
Whichever you choose, the payload must carry the click id (cid), the amount, and the status, plus the signature values (exp, sig) that came in on the redirect. Without a valid signature, the conversion is rejected.
Step 4: How signing and validation work
Every conversion is checked before it's counted. This is the part that keeps your revenue data honest.
- Signature check. ShortlyLink recomputes the HMAC-SHA256 signature for the incoming click id and expiry and compares it to the
sigyou returned. The comparison is timing-safe — it doesn't short-circuit on the first mismatched byte, which prevents attackers from probing the secret one character at a time. If the signatures don't match, the conversion is rejected. - TTL check. The signature is valid for 24 hours from the redirect. This is the
expvalue. If a conversion arrives after that window, it's rejected as a late conversion. That's deliberate: it bounds how long a signed click stays spendable and stops stale or replayed data from trickling in days later.
The 24-hour window matters for affiliate offers with delayed confirmations. If your network only confirms conversions on a nightly batch, make sure that batch fires the postback within the day — otherwise the signature will have expired and the conversion won't be attributed.
Step 5: Deduplication by click id
Networks retry. Pixels fire twice when a user refreshes the thank-you page. Postbacks get re-sent when the first response times out. Left alone, all of this would inflate your conversion count.
ShortlyLink deduplicates by click id. The first valid conversion for a given cid is recorded. Any repeat for the same click id returns HTTP 409 Conflict and is not counted again. One click, one conversion — no double counting, no manual cleanup.
This is why the click id is the anchor of the whole system: it's both how a conversion is attributed and how a duplicate is caught. You don't need to build idempotency on your side; the 409 tells you ShortlyLink already has that conversion.
Step 6: Payout clamping
Amounts are never trusted blindly. Before a conversion's value is added to your revenue, it's clamped:
- The amount is capped at the link's
maxPayout, or the default max of 1000 if you didn't set one. - Any negative,
NaN, orInfinityamount is coerced to 0.
So a network that posts a malformed amount, a negative refund value, or a wildly out-of-range figure can't corrupt your totals. The worst case is a conversion recorded at 0 or clamped to your ceiling — never a phantom windfall. This is the second half of the safety story you started in Step 1: set a realistic maxPayout, and clamping enforces it automatically.
Step 7: How statuses normalize
Affiliate networks use a zoo of status strings — "approved", "paid", "hold", "declined", "reversed", and dozens of vendor-specific variants. ShortlyLink normalizes every incoming status into one of three buckets:
- confirmed — the conversion is validated and counts toward revenue.
- pending — awaiting confirmation (for example, a sale still inside a return window).
- rejected — the conversion was declined or reversed.
If a status comes in that ShortlyLink doesn't recognize, it defaults to confirmed. Keep that in mind when you map your network's macros: send an explicit pending or rejected where you mean it, because anything unrecognized is treated as a real, confirmed conversion.
Step 8: See your results
Once conversions are flowing, you have three ways to read them:
- Revenue dashboard. Conversions and revenue appear alongside your click analytics, with widgets for totals, conversions, conversion rate, and revenue over time. You can build custom dashboards from ShortlyLink's widget set and view presets up to roughly six months, plus custom date ranges.
- CSV export. Pull conversions and revenue out for your own spreadsheets or BI tools. Exports run up to 10,000 rows by default (hard max 100,000), and truncation is clearly announced so you never silently lose data.
- Conversion webhooks. Optionally push each conversion to your own systems in real time. ShortlyLink's webhook events include
conversion(along withclick,bot_detected,link_expired, andanomaly), delivered HMAC-signed and SSRF-guarded so you can trust what arrives.
Together these let you reconcile ShortlyLink's numbers against your network's reporting and spot discrepancies early.
Common pitfalls
A few mistakes trip up almost everyone the first time. Avoid these:
- Don't test the link with curl. ShortlyLink scores every click for fraud, and scripting user agents like
curl,wget,python-requests, and headless browsers score high. A high enough score trips the block tier and returns a 403 page — so your "test" never even reaches the redirect, and you'll think tracking is broken when it isn't. Test in a real browser, or use a UA/IP allowlist entry if you must automate. - Signatures expire after 24 hours. A conversion signed at redirect time is only valid for a day. If your network confirms conversions slowly, make sure the postback fires inside that window, or the conversion will be rejected as late.
- Weighted rotation suppresses A/B testing on the same link. ShortlyLink resolves a redirect through an exclusive priority chain, and weighted rotation and A/B testing are mutually exclusive — rotation wins. If you enable both on one link, your A/B test silently won't run. Use separate links, or pick one mechanism per link.
- Preserve
cid,exp, andsigend to end. If a redirect or landing-page framework on your side strips query parameters, the signature values never make it back, and every conversion fails validation. Confirm the trio survives all the way to your thank-you page or postback macro.
Have a question this didn't cover? The FAQ goes deeper on tracking, analytics, and fraud handling.
Putting it together
The reliable pattern for most affiliate marketers is: create the link with a sensible maxPayout, wire your network's server-to-server postback to GET /postback (falling back to the pixel only when you must), and let ShortlyLink handle signing, the 24-hour TTL, dedup by click id, payout clamping, and status normalization. Then read confirmed revenue in the dashboard, export what you need, and push conversion webhooks into your stack. You get attribution you can defend — every counted conversion is signed, unique, and inside a bounded window.
Start free at shortlylink.com/register — no credit card, limited beta spots.