Skip to main content

When to use S2S clicks

Normally the user taps your ad, opens the Linkrunner tracking link in a browser, and is redirected to the store. Linkrunner records the click on the way through. Some placements never open a browser. OEM app-store icons on Xiaomi, OPPO and vivo, preloaded placements, and some in-app units send the user straight to the Play Store or App Store. Linkrunner never sees those clicks, so their installs look organic. For this traffic, your server reports each click to Linkrunner, and the user goes directly to the store as before. It works like server-to-server clicks in AppsFlyer (redirect=false), and accepts the same parameter names.
The advertiser turns on S2S clicks for each partner separately. Ask them, or Linkrunner support, to turn them on for your partner account before you send traffic. Until then, requests are rejected with partner_not_enabled. S2S clicks stop if the advertiser disconnects your account.

How it works

Linkrunner matches the install to your click in one of three ways, strongest first: Send a device ID whenever you have one. IP matching is a fallback: users behind the same public IP can be confused with each other. Postbacks work exactly as for regular clicks. Your existing postback templates, event mapping and postback logs apply unchanged.

Set it up

1

Create the campaign link

Create the link in your affiliate dashboard as usual. See Create a campaign link. You get a tracking link like this:
2

Turn it into the S2S URL

Keep your parameters, and send them to https://s2s.linkrunner.io/v1/click/<app_id> instead. <app_id> is the app’s Android package name (com.example.app) or its App Store ID (id1234567890), the same app ID you use with AppsFlyer.Then add the device fields your server has: gaid or idfa, and optionally ip, ua and click_time.
You can name the advertiser by the tracking link’s domain instead: https://s2s.linkrunner.io/v1/click?d=app.example.com&c=.... Use d if the advertiser tells you their test and live apps share an app ID and the same campaign code.
3

Fire it from your server when the user clicks

Replace your macros and call the URL with GET, at the moment of the click. The user doesn’t wait on this call; send them to the store directly.A 200 with "status":"accepted" means the click is recorded. See retries for the other responses.
4

Test it end to end

Send one click with the GAID of a test device, then install and open the app on that device. The install postback arrives with your tid in {click_id} / {tid}. Check it in Postback logs.
Send each click as it happens. Linkrunner only attributes an install to a click it received first, and there is no way to re-attribute an install afterwards. Clicks older than 24 hours are rejected.

Coming from AppsFlyer

If you already send S2S clicks to AppsFlyer, you can reuse that template. Linkrunner takes the app ID in the path just like AppsFlyer and accepts the AppsFlyer parameter names, so only the host and c change. An AppsFlyer template like this:
becomes:

Retries

Retrying is safe. The same tid for the same campaign always returns the same click_id and is stored once.
  • Retry 429 and 503, after the Retry-After delay.
  • Don’t retry other 4xx responses. Fix the request instead. The reason tells you what’s wrong.
Keep tid unique per campaign for good. A reused tid is treated as a retry of the earlier click, so the new click is not recorded.
See the S2S Click API reference for every parameter, response and rejection reason.

Troubleshooting

Every request returns unknown_campaign. c must be the campaign code from your Linkrunner tracking link. An AppsFlyer campaign name in c doesn’t match. Requests return partner_not_enabled. The advertiser hasn’t turned on S2S clicks for your partner account on this app, or c is a campaign that isn’t yours. Changes take up to 5 minutes to apply. Requests return unknown_app. Check the app ID against the store listing: the package name for Android, id plus the number for iOS. An app newly set up in Linkrunner can take a few minutes to be recognised. Requests return ambiguous_app. The advertiser has more than one Linkrunner project for this app (for example test and live), and the campaign code exists in both. Send d with the tracking link’s domain instead of the app ID. Requests return unreplaced_macro. A value still contains a macro such as {click_id} or %7Bgaid%7D. Your platform must replace every macro before it sends the request. Clicks are accepted but installs aren’t attributed. Check that the click carries the user’s real GAID or IDFA, not a placeholder, and that it arrives before the install. With IP only, make sure ip is the user’s device IP, not your server’s. A device that clicked another source more recently may be credited to that click instead. Postbacks arrive without your click ID. Confirm the click had tid (or clickid) and the response was accepted. Need help? Contact support@linkrunner.io