Skip to content

Postbacks and Macros ​

The macros Linkrunner fills into your postback URLs, with examples for each conversion

Overview ​

When a conversion is attributed to your click, Linkrunner sends a server-to-server postback to your endpoint. You give Linkrunner a postback URL that contains macros. Linkrunner replaces each macro with the real value and sends the request.

You provide one URL template per conversion you want to receive (install, signup, in-app event). Linkrunner sends the request as an HTTP GET.

Event mapping ​

Linkrunner sends these postbacks automatically:

  • Install, for every install attributed to your click.
  • Signup, once a signup postback is set up for you.

In-app events (for example a purchase) are sent only after they are mapped. Events without a mapping are not sent to you.

Either side can add a mapping:

  • The advertiser, from Integrations → your network → Event Mapping in their Linkrunner dashboard.
  • You, from Event Mapping in your affiliate dashboard.

Each mapping picks one of the advertiser's events and the name it is sent to you as, for example purchase sent as sale. It can also turn on Send Revenue so the postback includes the event's revenue and currency.

See Event Mapping for a walkthrough of the screen, including how to apply a mapping to all your customers or only one.

Missing an event you expected? Check that it has a mapping for this advertiser.

Allowlist Linkrunner postback IPs ​

If your endpoint restricts incoming traffic by source IP, allowlist both Linkrunner production egress addresses:

8.234.94.188/32
8.234.80.204/32

Postbacks may originate from either address. Add both before testing or activating your integration.

These are postback URL macros. They are different from the macros your platform may use in the click tracking link. Your platform must resolve click macros before sending traffic to Linkrunner.

Rejected conversions ​

A customer can run Fraud Control rules that reject conversions attributed to you. To be told about them, add rejection postback URLs in your affiliate dashboard under Settings → Postback URLs → Rejection postbacks.

URLCalled for
Install Rejection URLA rejected install
Event Rejection URLA rejected in-app event, signup, or revenue event

The Rejection postbacks section in the affiliate Settings page, with both URLs

Both are optional. Leave one empty and you receive none of that kind. You can add them once your application is approved.

A rejection is sent only for a conversion you would otherwise have received, so your event mappings still apply. It is sent once and never retried, whatever your endpoint answers. Treat it as a conversion you must not pay out on. Your usual postback URL is not called for a rejected conversion.

Rejection macros ​

A rejection URL can use the macros above, plus three that exist only in a rejection URL:

MacroValue
{click_id}Your click ID for the rejected conversion
{event_name}install, or the name you receive the event under
{rejection_reason}Reason codes, comma separated, for example click_injection.ctit_seconds
{rejection_reason_label}The same reasons in plain words, separated by ;
{rejected_at}When Linkrunner rejected the conversion, in Unix seconds

For example, this rejection URL:

https://postback.example.com/reject?click_id={click_id}&event={event_name}&reason={rejection_reason}&at={rejected_at}

is sent as:

https://postback.example.com/reject?click_id=a1b2c3d4e5&event=install&reason=device_farm.manufacturer%2Cclick_injection.ctit_seconds&at=1790353906

Reason codes ​

Each code is <rule type>.<property>: the kind of rule that matched, and the property it matched on. A code can be a rule type alone when the rule did not match on a single property. A conversion can carry several codes, and each code appears once.

A rule type that is not in this list is sent as custom_rule, for example custom_rule.device_model. New codes can be added, and existing codes do not change meaning, so treat a code you do not recognise as a rejection.

Rule typeMeaning
click_injectionClick injection
click_floodingClick flooding
click_flooding_ipClick flooding from one IP
click_flooding_deviceClick flooding from one device
install_hijackingInstall hijacking
sdk_spoofingSDK spoofing
sdk_spoofing_ip_mismatchSDK spoofing with IP mismatch
flagged_click_installInstall from a fraudulent click
flagged_click_reinstallReinstall from a fraudulent click
anonymous_trafficAnonymous traffic
datacenter_ipAnonymous traffic from a data center IP
datacenter_reinstallAnonymous traffic reinstall
datacenter_ip_mismatchAnonymous traffic with IP mismatch
botsBots
bots_user_agentBots by user agent
device_farmDevice farm
custom_ruleCustom rule
PropertyMeaning
os_versionOS version
app_versionApp version
package_versionSDK version
platformPlatform
countryCountry
localeLocale
carrierCarrier
manufacturerManufacturer
device_modelDevice model
att_statusATT status
limit_ad_trackingLimit ad tracking
gaidGoogle advertising ID
idfaIDFA
ip_addressServer-observed IP
device_ipSDK-reported device IP
device_ip_matches_server_ipDevice IP matches server IP
attribution_sourceAttribution source
ad_network_idAd network
campaign_idCampaign
is_reinstallIs reinstall
signature_verification_statusSDK signature status
ctit_secondsClick-to-install time (s)
install_ref_referrer_click_tsPlay referrer click timestamp
install_ref_install_begin_tsPlay install-begin timestamp
click_after_install_beginClick recorded after install began
first_open_atFirst open timestamp
matched_click_is_fraudMatched a flagged click
matched_click_fraud_reasonsFlagged click reasons
event_nameEvent name
event_typeEvent type
amountRevenue amount
currencyCurrency
revenue_typeRevenue type
revenue_statusRevenue status
days_since_clickDays since click
user_agentUser agent
osOS
device_typeDevice type
device_vendorDevice vendor
browser_nameBrowser
referrer_domainReferrer domain
device_idDevice ID (GAID or IDFA)
linkClick URL
is_uniqueIs unique click

The Linkrunner dashboard shows a click tracking link for your campaign. For affiliate campaigns, the click link uses Linkrunner's click parameters:

https://track.example.com/?c=OgWmhiSXhG&tid={click_id}&s2={campaign_id}&s3={publisher_id}&gaid={gaid}

Your platform resolves the placeholders before redirecting the user to Linkrunner. The actual click should look like this:

https://track.example.com/?c=OgWmhiSXhG&tid=a1b2c3d4e5&s2=camp_88&s3=pub_4471&gaid=38400000-8cf0-11bd-b23e-10b96e40000d
ParameterUse
cLinkrunner campaign identifier. Keep the value from the dashboard.
tidYour click ID. Linkrunner returns this in postbacks as {click_id} and {tid}.
s2, s3, s4Optional passthrough values. Linkrunner returns them in postbacks as {s2}, {s3}, and {s4}.
gaidAndroid Google Advertising ID, when available.
idfaiOS advertising ID, when available.

Use these parameter names in the URL. For example, use tid={click_id} instead of utm_id={click_id}, and use s2={campaign_id} instead of cc={campaign_id}.

Do not add postback-only values such as postbackKey, event, event_name, or crc to the click tracking link. If your postback endpoint requires a secret key, configure it privately with Linkrunner.

Macro syntax ​

Macros are written in lowercase inside curly braces:

{macro_name}

Rules:

  • Linkrunner replaces every macro it recognizes with the conversion's value.
  • Values are URL-encoded automatically. Do not encode the macros yourself.
  • A macro with no value for a given conversion is replaced with an empty string. For example, {idfa} is empty on an Android install.
  • Text that is not a recognized macro is left untouched, so static query parameters are safe.
  • All timestamps are Unix seconds in UTC.

Any macro on this page can arrive empty when the value is not known for that conversion. Build your endpoint to accept empty values rather than reject the request.

Only use the postback macros listed below in your postback URL template. Linkrunner leaves unsupported campaign, event, platform, sub, and secret placeholders unchanged.

Macro reference ​

Identifiers ​

MacroDescription
{click_id}The tid value you sent on the tracking link. Use this to match the postback to your click.
{tid}Same value as {click_id}.
{install_id}Linkrunner's unique identifier for the install.
{campaign_id}Your campaign ID from the click link when you sent one. Otherwise Linkrunner's numeric campaign ID (for example 4471).
{cc}Same value as {campaign_id}.

Event ​

MacroDescription
{event_name}The conversion name: install, signup, or the mapped in-app event name (for example purchase, or your goal name if the mapping renames it).
{event}Same value as {event_name}.
{timestamp}Time when Linkrunner builds the postback, as a Unix timestamp in seconds.

{timestamp} is when the postback was sent, not when the conversion happened. Use {event_time} for the time of the event itself.

Time ​

All three are Unix timestamps in seconds, UTC.

MacroDescriptionExample
{click_time}Time of the click that the conversion was attributed to.1789653202
{install_time}Time of the install, measured as the first app open received by Linkrunner's servers.1789653349
{event_time}Time the event happened. On an install postback this is the same value as {install_time}.1789667620

{install_time} is the first app open as received by Linkrunner's servers, the same definition other MMPs use. It is not the Play Store download or install-begin time.

App ​

MacroDescriptionExample
{bundle_id}App bundle ID (iOS) or package name (Android).com.example.app
{app_version}Version of the app the user is running.15.2.209

Revenue ​

MacroDescription
{revenue}Revenue amount in major currency units, with two decimal places (for example 9.99). Populated only on events that carry revenue and whose mapping has Send Revenue on.
{sale_amount}Same value as {revenue}.
{amount}Same value as {revenue}.
{currency}ISO 4217 currency code (for example USD, INR).

{revenue} is in major currency units, not minor units. 9.99 means 9.99, not 9.99 cents. Parse it as a decimal amount.

Device ​

MacroDescriptionExample
{gaid}Google Advertising ID (Android).38400000-8cf0-11bd-b23e-10b96e40000d
{idfa}iOS Advertising ID (Apple).6D92078A-8246-4BA4-AE5B-76104861E7DC
{device_brand}Device brand.POCO
{device_model}Device model. Android sends a readable name, iOS sends the hardware identifier.Xiaomi 2302EPCC4I (Android), iPhone15,2 (iOS)
{os_version}Operating system version.13
{platform}android or ios, always lowercase.android

Network ​

MacroDescriptionExample
{ip}The device's public IP address at install.203.0.113.24
{user_agent}The user agent of the matched click, not of the app's install request.Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Mobile Safari/537.36

{user_agent} and {click_time} come from the click the conversion was matched to. {ip} is the device's public IP at install time.

Attribution ​

MacroDescriptionExample
{is_reinstall}1 if the user had installed the app before, 0 if this is a first install.0
{touch_type}The type of touch the conversion was attributed to: click, or impression for a view-through install.click

{touch_type} is impression only when the install was credited to an impression you reported through S2S impressions.

Click passthrough ​

MacroDescription
{s2}The s2 value you sent on the tracking link.
{s3}The s3 value you sent on the tracking link.
{s4}The s4 value you sent on the tracking link.

Static values ​

If your endpoint needs a fixed query parameter, add it as plain text in the URL template:

https://partner.example.com/postback?tid={click_id}&source=linkrunner

Do not use {secret.postbackKey}. If your endpoint requires a secret key, configure it privately with Linkrunner so it is not shown in dashboard tracking links or public examples.

Not available ​

  • Country code. There is no country macro. Derive it from {ip} if you need one.
  • App store ID. Use {bundle_id}. On Android it is the same value as the Play Store listing ID.
  • Retargeting and re-engagement conversions. Linkrunner does not send affiliate postbacks for these.

Examples ​

Install postback ​

Your template:

https://partner.example.com/postback?tid={click_id}&event={event_name}&gaid={gaid}&s2={s2}&click_time={click_time}&install_time={install_time}&bundle_id={bundle_id}&platform={platform}

What Linkrunner sends:

https://partner.example.com/postback?tid=a1b2c3d4e5&event=install&gaid=38400000-8cf0-11bd-b23e-10b96e40000d&s2=camp_88&click_time=1789653202&install_time=1789653349&bundle_id=com.example.app&platform=android

Signup postback ​

https://partner.example.com/postback?tid={click_id}&event={event_name}&s2={s2}&event_time={event_time}

Purchase postback with revenue ​

Your template:

https://partner.example.com/postback?tid={click_id}&event={event_name}&amount={revenue}&currency={currency}&event_time={event_time}&ts={timestamp}

What Linkrunner sends:

https://partner.example.com/postback?tid=a1b2c3d4e5&event=purchase&amount=9.99&currency=USD&event_time=1789667620&ts=1789667623

Device and attribution detail ​

Your template:

https://partner.example.com/postback?tid={click_id}&event={event_name}&brand={device_brand}&model={device_model}&os={os_version}&app_version={app_version}&ip={ip}&reinstall={is_reinstall}&touch={touch_type}

What Linkrunner sends:

https://partner.example.com/postback?tid=a1b2c3d4e5&event=install&brand=POCO&model=Xiaomi+2302EPCC4I&os=13&app_version=15.2.209&ip=203.0.113.24&reinstall=0&touch=click

Deduplication ​

Linkrunner retries a postback if your endpoint does not respond with a success status. Treat postbacks as at-least-once. Deduplicate on your click ID plus event name, or use a fixed value you send in s4 on the click link.

Formatting reference ​

ValueFormat
Timestamps ({timestamp}, {click_time}, {install_time}, {event_time})Unix seconds, UTC.
Revenue ({revenue})Decimal, two places, major currency units.
Currency ({currency})ISO 4217 three-letter code.
Platform ({platform})Lowercase android or ios.
Reinstall flag ({is_reinstall})1 or 0.
All valuesURL-encoded.

Troubleshooting ​

A macro arrives empty. The value was not available for that conversion. For example, {idfa} is empty on Android, and {revenue} is 0 on events without revenue. Device advertising IDs depend on the value being present on the click and on user consent.

A macro arrives as literal text. That macro is not supported by the current Linkrunner postback renderer. Use one of the macros listed on this page.

You do not receive an in-app event. In-app events are sent only after they are mapped. Ask the advertiser to map the event, or add the mapping yourself from Event Mapping in your affiliate dashboard. See Event mapping.

You want to check whether a postback reached you. Open Postback Logs in your affiliate dashboard. It shows every conversion sent to you and what your endpoint answered.

You receive the same conversion twice. Postbacks are at-least-once. Deduplicate on your click ID plus event name, or use a fixed value you send in s4 on the click link.

Revenue looks 100x too large or too small.{revenue} is in major units (9.99), not minor units. Do not multiply or divide by 100.

Need help? Contact support@linkrunner.io