linkrunway.

Events and revenue

POST /v1/track accepts consented events. Publishable keys produce unverified client events. Server keys produce verified events and are required for PURCHASE, SUBSCRIPTION, and REFUND.

Event fields

FieldRequirement
eventIdRequired stable string, 1–150 characters
typeINSTALL, OPEN, SIGNUP, PURCHASE, SUBSCRIPTION, REFUND, or CUSTOM
consentRequired literal true
nameOptional event name, at most 120 characters
clickTokenOptional signed attribution token, at most 1,500 characters
externalUserIdOptional stable customer ID, 1–200 characters; canonical identity requires a server key
amountInteger minor units, 0–1,000,000,000; default 0; non-financial events must use 0
currencyThree uppercase letters; default USD
originalEventIdRequired for refunds and forbidden for other types
metadataFlat metadata object; see API conventions
occurredAtOptional ISO timestamp; defaults to receipt time
installIdOptional UUID; SDKs manage installation identity
attestationOptional device attestation token, at most 2,000 characters

Timestamps must be within the previous 90 days and no more than 60 seconds in the future. Synchronize backend clocks. A provided invalid or expired click token fails validation; do not manufacture tokens.

Send trusted revenue

Verify payment with your payment provider in your backend first. Derive amount, currency, customer ID, and event ID from that verified payment record. Persist the delivery in a durable outbox before calling LinkRunway.

sh
# Example only: send after verifying the payment in your backend.
curl --fail-with-body https://api.linkrunway.com/v1/track \
  -H "Authorization: Bearer $LINKRUNWAY_SERVER_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"eventId":"payment_example_001","type":"PURCHASE","externalUserId":"customer_example_001","amount":1999,"currency":"USD","consent":true}'

1999 represents USD 19.99. Supply a genuine clickToken when your consented journey has one, or let the configured customer attribution policy evaluate eligible prior touches. A successful event can be unattributed. Revenue ingestion does not promise a commission: attribution, partner status, fraud checks, and event type also matter.

Idempotency

A successful response is { id, attributed, duplicate }. Retrying an accepted event ID returns the original record with duplicate: true. Changing its type, amount, currency, or refund reference returns 409. Other retry fields do not rewrite an already-recorded event. Keep the complete original payload stable.

Client events are stored under the reserved app: namespace; server events must not use IDs beginning with app:. A client cannot reserve a future server payment ID. Deduplication is workspace-scoped, so never rely on the same ID to deduplicate across workspaces.

For invoice renewals, use the provider's unique paid invoice ID. For refunds, use a unique refund ID. Never create a fresh random event ID merely because a network request timed out.

Refunds

json
{
  "eventId": "refund_example_001",
  "type": "REFUND",
  "originalEventId": "payment_example_001",
  "amount": 500,
  "currency": "USD",
  "consent": true
}

Send the original caller-supplied event ID, not LinkRunway's internal id. Refunds must refer to an eligible original revenue event in the same workspace and use its currency. Use positive minor units; the service records the reversal. Partial refunds must not exceed the remaining original amount. A retry must retain its refund ID and amount.

Delivery and attribution

Use event webhooks to consume recorded events. Treat verified and attribution as separate facts. A client SIGNUP is telemetry; a server-authenticated SIGNUP can identify the customer. A webhook is not a second payment authorization.

Use errors and retries for delivery recovery and testing for a complete verification sequence.