Skip to main content
All endpoints are POST requests to https://api.linkrunner.io with a JSON body and Content-Type: application/json.

Authentication

Send your project token in the body of every request as token. That is the only credential these endpoints need.
{ "token": "YOUR_PROJECT_TOKEN" }

Common fields

These fields appear on most requests. Send them on every call once your install is registered.
FieldTypeDescription
tokenstringRequired. Your project token.
platformstringUse "ANDROID" or "IOS".
install_instance_idstringThe UUID you generate once and reuse. See Install instance ID.

Rules

  • Rate limit: 25 requests per second per token. Over the limit returns 429.
  • Response envelope: most endpoints return { "msg": string, "status": number, "data": object }. init is the exception (see below).
  • Call from the device so Linkrunner sees the device IP.
This reference uses Android examples. On iOS, send "platform": "IOS" and a different device_data shape (IDFA, IDFV, and adservices_attribution_token instead of GAID and the install referrer). The init, trigger, capture-event, and capture-payment responses may also include SKAdNetwork values (fine_conversion_value, coarse_conversion_value, lock_postback). See iOS device data.

init

POST /api/client/init
Registers an install or app open and starts attribution. Call once on app start.
FieldTypeDescription
tokenstringRequired.
install_instance_idstringThe persisted UUID. Send it so events tie to this install.
device_dataobjectDevice signals. See Collecting device data.
platformstring"ANDROID".
app_versionstringYour app’s version name.
package_versionstringA version string for your integration.
linkstringOptional. The deeplink the app was opened with, if any.
debugbooleanOptional.
Returns 202. Attribution runs in the background, so the response only acknowledges receipt.
{
  "processing_id": "f1e2...c9",
  "status": "accepted",
  "message": "Install event accepted for processing",
  "success": true
}
To read the attribution result, poll attribution-data with the same install_instance_id.

attribution-data

POST /api/client/attribution-data
Returns the attribution result for an install. Safe to poll. The result is cached for 24 hours.
FieldTypeDescription
tokenstringRequired.
install_instance_idstringThe install to look up.
device_dataobjectOptional. Include install_ref so the Meta referrer can be resolved.
platformstring"ANDROID".
{
  "msg": "Attribution data retrieved successfully!",
  "status": 200,
  "data": {
    "deeplink": "https://app.example.com/product/123",
    "campaign_data": {
      "id": "1234",
      "name": "summer_sale",
      "type": "INORGANIC",
      "ad_network": "META",
      "group_name": "prospecting",
      "asset_group_name": "video_ads",
      "asset_name": "reel_01",
      "installed_at": "2026-06-14T10:00:00Z",
      "store_click_at": "2026-06-14T09:55:00Z"
    },
    "attribution_source": "META"
  }
}
For an organic install, campaign_data is null and attribution_source is "ORGANIC".

trigger (signup)

POST /api/client/trigger
Identifies the user and ties the install to your user ID. Call when the user signs up or logs in.
FieldTypeDescription
tokenstringRequired.
user_dataobjectThe user, see below.
dataobjectPass-through bag. Include device_data inside it.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".
customer_created_atstringOptional. ISO date the user account was created.
is_first_time_customerbooleanOptional.
user_data fields (only id is needed):
FieldTypeDescription
idstringYour user ID.
name, email, phonestringUser details.
mixpanel_distinct_id, amplitude_device_id, posthog_distinct_id, braze_device_idstringAnalytics IDs for those integrations.
ga_app_instance_id, ga_session_idstringGoogle Analytics IDs.
{
  "token": "YOUR_PROJECT_TOKEN",
  "platform": "ANDROID",
  "install_instance_id": "f1e2...c9",
  "user_data": { "id": "user_123", "email": "user@example.com" },
  "data": { "device_data": { "...": "..." } }
}
{ "msg": "Trigger processed successfully", "status": 200, "data": { "deeplink": "", "trigger": true } }

set-user-data

POST /api/client/set-user-data
Updates user details after signup, for example when the user adds a phone number. Not a replacement for signup.
FieldTypeDescription
tokenstringRequired.
user_dataobjectSame shape as signup.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".

capture-event

POST /api/client/capture-event
Tracks a custom event. Events are only stored for attributed users, so call signup first.
FieldTypeDescription
tokenstringRequired.
event_namestringRequired.
event_dataobjectOptional. Custom attributes. Add amount as a number to share revenue with ad networks.
install_instance_idstringThe persisted UUID.
user_idstringOptional.
platformstring"ANDROID".
{ "msg": "Event capture request received!", "status": 200, "data": { "message": "Event capture request received!" } }

capture-payment

POST /api/client/capture-payment
Tracks revenue. Like events, the user must be attributed via signup.
FieldTypeDescription
tokenstringRequired.
amountnumberPayment amount. Must be zero or greater.
user_idstringThe paying user.
payment_idstringOptional. Used to deduplicate. Sending the same payment_id twice is ignored.
typestringOptional. Defaults to DEFAULT.
statusstringOptional. Defaults to PAYMENT_COMPLETED.
event_dataobjectOptional. Ecommerce attributes.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".
type values: FIRST_PAYMENT, SECOND_PAYMENT, ONE_TIME, RECURRING, WALLET_TOPUP, FUNDS_WITHDRAWAL, SUBSCRIPTION_CREATED, SUBSCRIPTION_RENEWED, SUBSCRIPTION_CANCELLED, SUBSCRIPTION_REFUNDED, SUBSCRIPTION_BILLING_ISSUE, DEFAULT. status values: PAYMENT_INITIATED, PAYMENT_COMPLETED, PAYMENT_FAILED, PAYMENT_CANCELLED.
{ "msg": "Payment capture request received!", "status": 201, "data": { "message": "Payment capture request received!" } }

remove-captured-payment

POST /api/client/remove-captured-payment
Removes a captured payment, for a refund. Provide payment_id or user_id.
FieldTypeDescription
tokenstringRequired.
payment_idstringThe payment to remove.
user_idstringRemove payments for this user.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".

update-push-token

POST /api/client/update-push-token
Stores the device push token, used for uninstall tracking.
FieldTypeDescription
tokenstringRequired.
push_tokenstringThe FCM token.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".

integrations

POST /api/client/integrations
Sends third-party IDs, such as a CleverTap ID.
FieldTypeDescription
tokenstringRequired.
integration_infoobjectFor example { "clevertap_id": "..." }.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".
POST /api/client/handle-deeplink
Reports a deeplink open for remarketing and reattribution. Call when your app opens from a deeplink.
FieldTypeDescription
tokenstringRequired.
deeplink_urlstringThe deeplink the app opened with.
device_dataobjectDevice signals.
meta_install_referrerobjectOptional. The Meta referrer object if available.
install_instance_idstringThe persisted UUID.
platformstring"ANDROID".
{ "msg": "Deeplink processed", "status": 200, "data": { "deeplink": "https://app.example.com/x", "is_linkrunner": true, "processing": false } }

Errors

CodeMeaning
400Missing required field or invalid token.
401Invalid token (on attribution-data).
429Rate limit exceeded (25 req/s per token).
500Server error. Retry with backoff.
Need help? Contact support@linkrunner.io