SDK Endpoints

The REST endpoints the LinkTrail SDKs call: resolve a link, record an install with its deferred deep link, record an open or an event, resolve a click.

These are the endpoints the iOS, Android, React Native and Flutter SDKs call, at https://backend.linktrail.io/v1. Use them directly only if you are building your own client — the SDKs already handle consent, retries, idempotency and the click token. The event endpoints need an API key in X-Api-Key (or Authorization: Bearer lt_live_…); link resolution is public.

MethodPathWhat it does
GET/links/resolveResolve a link URL to its deep-link payload (public)
POST/events/installRecord an install and return the deferred deep link
POST/events/openRecord a re-engagement open
POST/eventsRecord a custom or revenue event
GET/events/click/{token}Diagnostic: which link a click token belongs to

All of them are rate-limited per IP address and answer 429 over the limit. A custom client may send X-LinkTrail-SDK: <platform>/<version> to identify itself; it is optional and never changes the response.

GET /links/resolve?url=https://app.example.com/promo — or ?host=app.example.com&slug=promo — returns the link's DeepLink payload, or 404 when nothing matches. It records nothing, which is why it needs no key.

DeepLinkJSON
{ "slug": "promo", "url": "https://app.example.com/promo", "deepLinkPath": "/products/42",
  "iosUrl": "https://apps.apple.com/app/id123",
  "androidUrl": "https://play.google.com/store/apps/details?id=com.acme.shop",
  "fallbackUrl": "https://shop.example.com", "campaign": "Summer Sale", "channel": "Paid social",
  "utm": { "utm_source": "instagram" }, "customData": { "promoCode": "SUMMER" } }

Record an install

POST /v1/events/install — requestJSON
{ "identifier": "com.acme.shop", "platform": "Android", "clickId": "a1b2c3…(32-hex click token)",
  "deviceId": "1A2B3C", "consent": true }
201 responseJSON
{ "id": 991, "attributed": true, "deepLink": { /* DeepLink, or null if unattributed */ } }
  • identifier is required: the bundle ID or package name of an app registered in the key's workspace. platform, clickId, deviceId and consent are optional.
  • clickId is the deterministic click token, 32 hex characters. On Android it arrives through the Play Install Referrer (lt_click=<token>); on iOS the one-tap redirect page puts it on the clipboard. Without it the install can only be matched on IP address and platform, and only when that matching is switched on.
  • Send Idempotency-Key: install:<deviceId> so a retried install is not counted twice.
  • An unknown identifier answers {"code":404,"message":"No app found for this identifier in your workspace"}, with or without consent.

consent: false — route but don't record

With consent: false nothing is recorded: the answer is 200, not 201, has no id, attributed is always false, and only the click token is used for matching. deepLink is present only when a click matched — otherwise the key is left out. That is how a user who declined tracking still lands on the right screen.

consent: false → 200JSON
{ "attributed": false, "deepLink": { "deepLinkPath": "/products/aj1", "customData": { /* … */ } } }

Record an open

POST /v1/events/open — requestJSON
{ "identifier": "com.acme.shop", "platform": "iOS", "deviceId": "1A2B3C", "host": "app.example.com", "slug": "promo" }
201 responseJSON
{ "id": 1002, "attributed": true, "deepLink": { /* DeepLink */ } }

The opened link comes from host and slug when they are sent, otherwise from the attributed click.

Record an event

POST /v1/events — requestJSON
{ "identifier": "com.acme.shop", "name": "purchase", "value": 9.99, "currency": "USD", "deviceId": "1A2B3C" }
201 responseJSON
{ "id": 1100, "attributed": false }

identifier and name are required; value, currency, platform, clickId and deviceId are optional. currency is upper-cased.

Resolve a click token

GET /v1/events/click/460ce0f7bf4e840eb18da7fb793eb5f7 → 200JSON
{ "token": "460ce0f7…", "clickedAt": "2026-08-01T13:30:00Z",
  "platform": "Android", "country": "GB", "linkId": 42,
  "deepLink": { /* DeepLink — exactly what an install with this token would receive */ } }

A diagnostic that records nothing: it answers which link an lt_click token belongs to, so you can tell where a deferred install carrying it would be routed. Send the 32-hex token only, without the lt_click= prefix (anything else answers 400). A token that is unknown or from another workspace answers 404.

Not under /v1 and not called from app code: on each link domain, GET /{slug} is the smart redirect a tapped link hits, and /.well-known/apple-app-site-association and /.well-known/assetlinks.json are the association files Apple and Android fetch. See Domains & Association Files.