The Affiliate Marketer’s Playbook for ShortlyLink
An end-to-end playbook for affiliate marketers using ShortlyLink: structuring links and campaigns, wiring postback conversion tracking, avoiding common pitfalls, and reading the data.
If you run offers for a living, your links are your infrastructure. Every click has to be tracked, every conversion has to be attributed to the right campaign, and every dollar of payout has to be counted once — not twice, and not zero times. This playbook walks a solo affiliate or media buyer through a complete ShortlyLink workflow: how to structure campaigns, build links, wire conversions through the signed postback path, split traffic with redirect targeting, keep bots out of your numbers, and actually read the data.
Quick answer
Set up ShortlyLink for affiliate work in six moves: (1) one campaign per offer-plus-traffic-source, with consistent tags, UTM presets, and a branded custom domain; (2) create short links with readable custom back-halves and set a maxPayout before you send traffic; (3) wire conversions by reading the cid, exp, and sig off the redirected URL and passing them back through the network's S2S postback or a thank-you-page pixel; (4) optimize with geo rules plus either weighted rotation or A/B testing (they're mutually exclusive), and deep links for mobile offers; (5) let automatic bot and fraud scoring exclude junk traffic; (6) read per-link geo, device, referrer, and UTM breakdowns on 19-widget dashboards and export to CSV or JSON. Signatures expire after 24 hours, duplicate conversions are rejected with a 409, and testing a link with curl will get you blocked with a 403.
How should you structure campaigns and tags?
Structure is the part everyone skips and everyone regrets. The rule that scales best is one campaign per offer per traffic source. Not one campaign per offer. If you're running the same nutra offer on Facebook, native, and push, that's three campaigns — because you will eventually want to kill one source without touching the others, and you can't cleanly do that if they share a bucket.
On top of campaigns, use tags as a second axis. Campaigns answer "which offer and channel is this?" Tags answer everything else: vertical, angle, landing-page version, geo cluster, or the specific ad account. A link tagged nutra, advertorial-v3, tier1 tells you at a glance what it is, and lets you filter across campaigns later.
Then lock in your UTM presets so you stop hand-typing parameters. Pick a convention and never deviate:
utm_source— the traffic source (facebook,taboola,push)utm_medium— the format (cpc,native,email)utm_campaign— the campaign or offer nameutm_content— the creative or ad-set identifier
ShortlyLink captures all four on every click, and the dashboards break traffic down by UTM source and UTM campaign natively. Sloppy UTMs mean sloppy reports, so treat the preset as law.
Finally, run everything through a branded custom domain. Short links serve from go.shortlylink.com by default, but you can add your own domain, verify it with a DNS TXT record, and assign it per link. A branded back-half survives ad-network review better than a generic shortener, and it's yours — if you ever migrate, the brand recall stays with you.
A note on agencies and multiple clients: ShortlyLink's Teams is a member roster today — it doesn't share links across accounts, and roles don't grant cross-account permissions. If you're managing several clients, the practical pattern is one shared operator account with campaigns and tags as the client boundary, not separate seats.
How do you create links and set a payout cap?
Auto-generated short codes are 8 characters, which is fine for throwaway links. For anything you'll look at twice, set a custom back-half. The rules: 3 to 50 characters, letters, numbers, underscores and hyphens, reserved words blocked, and it has to be unique. Lookups are case-insensitive, so go.yourdomain.com/SummerVPN and /summervpn resolve the same — pick a casing convention and don't rely on case to disambiguate two links.
Give the back-half a job. /vpn-fb-t1 reads instantly in a report; /aX9k2 tells you nothing. Readable slugs also make it obvious when a link is pasted into the wrong ad.
When you're launching a batch — a hundred geos, a dozen creatives — use bulk import. You can push up to 500 links per request (rate-limited to roughly 10 imports an hour), sharing a campaign, tags, domain, expiry, and UTM set across the whole batch, with per-row error reporting so a single bad row doesn't sink the import.
The one setup step affiliates forget: set a maxPayout on the link before you send a single click. This is your safety rail. When conversions come back through the postback, the reported amount is clamped to the link's maxPayout (or a default ceiling of 1000 if you don't set one). Negative, NaN, or Infinity amounts collapse to 0. A misconfigured network or a hostile pixel can't inflate your revenue numbers past a cap you control. Set it to your actual offer payout with a little headroom and move on.
How do you wire conversions correctly?
This is the heart of affiliate tracking, and it's where most bad data comes from. ShortlyLink uses one signed path with two inputs: a server-to-server postback (GET /postback) and a browser pixel (POST /api/conversions/pixel). Both flow through the same signed, deduplicated pipeline.
Here's the mechanism. Every redirect appends three values to your destination URL:
| Parameter | Meaning |
|---|---|
cid |
the click ID — the specific click this conversion belongs to |
exp |
expiry timestamp for the signature |
sig |
an HMAC-SHA256 signature binding it all together |
Your job is to capture those three values off the landing URL and hand them back when the conversion fires. If you're using the network's S2S postback, map the network's click-ID macro to carry cid (and exp/sig) through so it can fire them back to ShortlyLink server-side — the most reliable method, because it doesn't depend on the browser. If you can't do S2S, drop a thank-you-page pixel that reads the same parameters and POSTs them. Either way, the signature is what proves the conversion is real and unmodified.
Three behaviors you have to design around:
- Signatures live for 24 hours. The
expvalue enforces a TTL — a conversion reported more than 24 hours after the click is rejected. For most offers this is a non-issue, but if your network batches postbacks daily, make sure they fire inside the window. - Deduplication is by click ID. Fire the same
cidtwice and the second one comes back HTTP 409 — no double counting. You don't need to build your own idempotency; it's handled. - Status normalization. Conversion statuses collapse to confirmed, pending, or rejected. Anything the system doesn't recognize normalizes to confirmed — so if your network sends an exotic status string, expect it to land as confirmed rather than getting dropped.
Conversions and revenue then show up on your dashboard, export to CSV, and can fire optional conversion webhooks if you want them piped into your own stack. For the full walkthrough, see how to track affiliate conversions.
How do you optimize traffic with redirect targeting?
One short link can resolve to different destinations depending on who's clicking. ShortlyLink runs an exclusive priority chain — each stage only fires if the earlier ones didn't already pick a target:
geo rules → weighted rotation → A/B test → mobile deep link → original URL
Start with geo rules. If your offer pays differently by country, or you have a tier-1 landing page and a tier-3 fallback, route by country at the top of the chain. Traffic that matches a geo rule is resolved there and never touches the stages below it.
Then choose one of the next two — and this is the trap that catches people: weighted rotation and A/B testing are mutually exclusive on the same link, and rotation wins. If you set both, rotation runs and your A/B test is silently suppressed. Decide up front:
- Use weighted rotation when you're load-balancing across multiple live offers or spreading risk across landing pages (say, 70/30 across two networks).
- Use A/B testing when you're measuring one page against another and want variant-level reporting to declare a winner.
Pick the tool that matches the question you're asking, and don't set both on one link.
For mobile offers, add deep links — an iOS target, an Android target, and a web fallback — so app-install offers open the right store or app while desktop clicks get the web page. This sits below rotation and A/B in the chain, catching mobile intent after your split logic has run.
A couple of adjacent features worth turning on: social cloaking serves a clean OG/Twitter preview to crawlers (Facebook, X, LinkedIn, Slack, Telegram, WhatsApp, Discord, Pinterest) while humans redirect through, and retargeting pixels (Facebook, Google gtag, TikTok, or a sandboxed custom pixel) fire before the 302 forward so you build audiences off your click traffic. The full breakdown lives in geo and A/B redirect targeting.
How do you keep your data clean?
Dirty traffic ruins optimization. You'll kill a good creative because bots inflated its clicks, or trust a source that's sending you nothing but scrapers. ShortlyLink scores this for you automatically.
Every click gets a fraud score from 0 to 100, built from signals like known bot user-agents, missing or inconsistent headers, scripting UAs (curl, wget, python-requests, headless browsers), rapid-fire clicks (8 within 10 seconds from the same fingerprint), and geographic "impossible travel" — the same fingerprint appearing in two countries within about 10 minutes.
Those scores map to risk tiers:
- Under 40 — normal, passes through
- 40 and up — logged for review
- 70 and up — challenged with a signed, roughly 2-minute JS challenge that non-JS bots fail
- 90 and up — blocked with a 403 page (recorded, but excluded from your stats)
Blocked and challenged junk never pollutes your analytics — bot traffic is excluded from stats automatically. If you have a legitimate monitoring IP or a partner's server hitting your links, you can add it to a UA or IP allowlist to short-circuit its score to 0.
On top of per-click scoring, an anomaly job runs every 5 minutes watching for two patterns: a traffic spike (recent clicks above 10 and more than 3× the trailing 5-minute average) and a bot surge (more than 5 bots and over half your traffic flagged). Either one fires an in-app or Slack alert, so you find out about a bad source or a pixel misfire in minutes, not at end-of-day reconciliation.
Worth knowing: no cookies or localStorage are used for click tracking. The visitor fingerprint is a one-way server-side hash, which is both a privacy posture and a reason your numbers hold up when browsers keep tightening cookie rules.
How do you actually read the data?
Reporting is where the workflow pays off. ShortlyLink gives you custom dashboards built from 19 widget types — totals, unique visitors, conversions, conversion rate, revenue, clicks over time, breakdowns by country, city, region, device, browser, OS, referrer, UTM source, UTM campaign, and source, plus top links and landing-page views and engagement. Build the view that matches how you buy: a media buyer's dashboard looks nothing like a content affiliate's, and you shouldn't force either into a default layout. Presets cover up to about 6 months, and you can set custom ranges.
Every link also gets its own per-link breakdowns — geo, device, referrer, and UTM — so you can drill from "this campaign is up" to "it's up because Android traffic from Germany converted on variant B." City-level geo is keyed with the country, so London, UK and London, Canada never get merged.
There's a real-time click feed over WebSocket when you want to watch a launch live, and each click carries a 16-character click ID, a unique-visitor flag, device and geo, referrer, UTMs, source (link vs QR scan vs bio tap), bot flag, fraud score, and A/B variant.
When you need the raw data — for your own spreadsheets, a P&L model, or an accountant — export to CSV or JSON. Exports run to 10,000 rows by default with a hard ceiling of 100,000, and truncation is announced clearly so you're never silently working with a partial file.
Pitfalls to avoid
- Don't test links with curl. Scripting user-agents trip the fraud scorer, and a curl request lands in the block tier — you'll get a 403 and think the link is broken. Test in a real browser (or add your testing IP to an allowlist).
- Signatures expire after 24 hours. A conversion reported outside the
expwindow is rejected. If your network batches postbacks, confirm they fire inside the day. - Rotation suppresses A/B. Weighted rotation and A/B testing are mutually exclusive on one link, and rotation wins. Set only the one you actually want, or your split test runs blind.
- Unknown postback statuses normalize to confirmed. If your network sends a status string ShortlyLink doesn't recognize, it lands as confirmed rather than pending or rejected — audit your status mapping so you're not counting soft conversions as hard ones.
- Skipping
maxPayout. Without a cap, revenue defaults to a 1000 ceiling per conversion. Set the real payout so a misfire can't distort your numbers.
Build the structure once — campaigns per offer and source, disciplined tags and UTMs, a branded domain, signed conversions, and clean split logic — and the rest of the platform does the counting for you. See the full feature set for everything that plugs into this workflow.
Ready to run your offers on real infrastructure? Start free at /register — no credit card, while beta spots last.