A/B split testing
Race 2–4 destinations against each other on one Zippy link — and see which variant actually OPENED THE NATIVE APP, not just which one got clicked.
A/B split testing
An A/B split test turns one short link into 2–4 weighted destinations. Zippy hands each visitor one of them, remembers which one they got, and then reports the number no other link tool can give you: which variant actually opened the native app.
A landing page can win on taps and still lose on app opens. That's the whole reason this exists.
Split testing is available on Hero and up, behind the ab-testing feature flag.
How the split works
Each variant is a destination (u) and a relative weight (w). Weights are relative, so
50/50 and 1/1 are the same split — the editor shows the resolved percentage as you type.
| Variant | Destination | Weight | Share of taps |
|---|---|---|---|
| A | https://shop.com/drop | 1 | 50% |
| B | https://instagram.com/p/abc123 | 1 | 50% |
Minimum 2 variants (one variant isn't a test), maximum 4 — a set that doesn't survive those bounds is treated as no test at all rather than silently truncated at redirect time.
The number nobody else shows you
Every other link tool tells you which variant got more clicks. Zippy stamps the variant index on the click, and the outcome pipeline records whether that tap ended in the real native app, a browser, or a broken hand-off. So you get the app-open rate per variant.
GET /api/links/:id/ab-stats
That's variant A winning on clicks and losing badly on the thing you actually wanted.
sampled: true is load-bearing. clicks comes from the redirects dataset and
appOpenRate is computed inside the outcomes dataset — the two are sampled independently.
Read it as a trend, never as an exact per-click ratio. A variant with no traffic yet still
appears, as a row of zeroes, so nothing silently vanishes from the report.
The report covers a rolling 90-day window and is Hero and up (the same tier as the
feature). On a lower plan the endpoint answers with an upgrade note instead of variant rows.
Set it up
Dashboard (web): in the ZIP form (or a link's editor), switch the destination mode to split test, then add 2–4 rows of destination + weight. A live split bar shows the percentage each variant will get.
Mobile app: the same fields live on a link's detail screen.
Via the API
Change the split later with PATCH /api/links/:id — send a new ab array to replace it,
or null to end the test. The short link never changes either way.
Every variant must be a valid http(s) URL:
Split test OR route — never both
A link can split-test or route by audience, not both. Routing sends a visitor somewhere based on who they are; a split test sends them somewhere at random so you can compare. Doing both at once would make the results meaningless, so Zippy rejects the combination instead of silently ignoring one:
The check runs on the effective values, so setting ab on a link that already routes is
the conflict — not just sending both fields in one request. Clear one, set the other; both
switches are instant and the link keeps redirecting throughout.
UTMs ride every variant
If the link also has UTM tracking, Zippy composes your utm_*
parameters onto every variant automatically — the same walker that handles routed and
scheduled destinations. Your stored variant URLs stay clean and editable; the composed ones
are what the engine serves. No variant can lose its campaign tags.
Nothing here can expire a link
A split test only decides which URL a tap resolves to. It cannot stop the link redirecting, cap its clicks, or 404 anyone — not when the test ends, not when you clear it, not ever. End a test and the link falls back to its default destination. That's the permanence guarantee, and A/B is built inside it, not around it.
Notes
- Hero and up, behind the
ab-testingflag. - 2–4 variants; weights must be positive numbers.
- Variants are
http(s); each one still springs the native app where one exists, in-app browser or not. - Per-variant results are a sampled trend over a 90-day window.
FAQ
How do I test two links to see which one works better?
Don't make two links — make one link with two destinations. Open the link's editor, switch
the destination mode to split test, and add both URLs with a weight each (1 and 1 for
an even split). Share the single short link. Zippy hands each visitor one of the two
destinations and reports how each one performed, including the app-open rate per variant.
Which variant is winning — clicks or app opens?
Both are in the report, and they often disagree. clicks is how many taps a variant got;
appOpenRate is the share of those taps that ended up inside the real native app. A
variant can take more clicks and still lose, because half its visitors got stranded in a
webview. The app-open rate is the number to optimise.
Can I split-test and route by geo on the same link?
No. Zippy returns an ab_routing_conflict error instead of letting both run. Random
assignment and audience-based assignment can't share one link without ruining the results.
Clear one before setting the other — switching is instant and the link never goes down.
What happens to my link when the test ends?
Nothing bad, ever. Clear the test ("ab": null) and the link goes back to serving its default
destination. The short URL, the QR code you printed, and every caption you already posted keep
working. A split test can't expire a link.
How many destinations can I test at once?
Between 2 and 4. One isn't a test; more than four is a cap the redirect engine enforces, so Zippy refuses the set rather than quietly dropping variants.
Read more
- Blog: Everyone else tells you which link got clicked. We tell you which one opened the app.
- Changelog: A/B split testing
- Sibling features: Scheduled destinations · Audience routing (mutually exclusive with A/B) · UTM tracking (rides every variant)
- Where to point a winning variant: Instagram DM automations attach a link to a DM, and broadcasts put one in an email — both report the same app-open outcome you just raced the variants on.