Skip to main content
The tracking script doesn’t do attribution in the browser. It gathers what it can see — the referral code in the URL, the device, the referrer, the ad click IDs — and posts it to a small set of public endpoints that do the actual work. Those endpoints are documented here because you can call them yourself: from a mobile app, from a server that has no browser to run a script in, or from a platform where you can’t inject JavaScript. All of them live under:
They take no API key. They’re identified by your program ID, which is public by design — it sits in a script tag on every page of your site — and they answer cross-origin requests from any domain.
No key means no proof of who is calling. Anyone who reads your program ID from your page source can post to these endpoints. They’re fine for clicks, cart events, and email capture, where the worst case is noise. For anything that creates a commission, use the authenticated sales endpoint instead, where the amount is asserted by your server with a secret key.

Which one to use

Record a click

Creates a click for an affiliate and returns it. The click ID it hands back is the identifier everything downstream hangs off, so this is usually the first call in any custom integration.
Everything else is optional context, stored on the click and surfaced in your reporting: fullLandingUrl, pathname, queryString, the UTM fields (utmSource, utmMedium, utmCampaign, utmTerm, utmContent), the ad click IDs (gclid, gbraid, wbraid, fbclid, msclkid, ttclid, twclid, liFatId), your own extClickId, referrer fields (documentReferrer, referrerDomain, referrerType), device fields (userAgent, browserName, browserVersion, osName, osVersion, deviceType), screen fields (screenWidth, screenHeight, colorDepth, pixelRatio, viewportWidth, viewportHeight), and language (language, languages). IP address and geolocation are not accepted from the body. Referly reads them from the request itself, so a click recorded from your server carries your server’s location rather than the visitor’s — worth knowing before you move click recording off the browser. Response
click.id is the click ID. Store it — as a string — against the visitor’s session and then their user record. When the referral code doesn’t belong to any affiliate in the program, the response is { "exists": false } with a 200. There is no error status: a bad code is treated as “nothing to track” rather than a failure. Check for the click key rather than the status code.
See click data for everything a click stores, and external click IDs for how extClickId connects Referly to an ad network or partner.

Capture an email

Records a referred customer with no revenue attached. Use it for sign-ups, trials, waitlists, and demo requests — anything where the person converts but hasn’t paid yet.
Response
404 with Affiliate not found means the affiliateId matched neither a click nor a link in that program. 400 means a required field was missing. Calling this twice for the same person doesn’t create two customers — the referral is matched on email within your program. What it will not do is move an existing customer to a different affiliate. First attribution wins.

Capture a sale

Records a customer and a sale in one call. This is what createPushLapSale() calls from the browser.
Response
This endpoint accepts no external identifier, so it cannot deduplicate. Call it twice and you create two sales and two commissions. Anything that might retry — a webhook handler, a job queue, a payment callback — belongs on the authenticated sales endpoint, which deduplicates on externalId.

Record an add-to-cart

Attaches a cart event to a click, so your funnel reporting can show clicks, carts, and purchases against each affiliate.
Response
A repeat call carrying an externalEventId that Referly has already stored for that source returns { "ok": true, "id": 5512, "deduped": true } instead of creating a second event. This is the one capture endpoint that is safe to retry — and only when you send externalEventId. 400 means programId or clickId was missing or malformed; 404 means the click doesn’t exist in that program.

Read your program’s tracking config

The script calls this on load to find out how your program is configured. Useful if you’re writing your own tracker and need the same settings.
{ "exists": false } comes back for an unknown program ID, and also when the account behind it has no active subscription. Responses are cached for a day, so a settings change can take that long to reach a cached response.

Calling these from your own code

Reasonable uses:
  • A mobile app. Record the click when someone opens a referral deep link, keep the click ID with the account, then report purchases through the API.
  • A platform that won’t let you inject scripts. Post the click yourself from wherever you can run code.
  • A redirect service of your own. Record the click as you redirect, then hand the click ID on to your site.
Things to get right:
  • Recording a click server-side loses the visitor’s context. The IP and location come from whatever machine makes the request, and the browser and device fields are only as good as what you pass in.
  • Store the click ID, not the referral code. A click ID ties everything to one specific visit; a code only identifies the affiliate.
  • Treat 200 with {"exists": false} as a failure. It means the code matched no affiliate.
  • Don’t record money here if the call can repeat. Only add-to-cart deduplicates, and only with externalEventId.

Report a sale

The authenticated way to record revenue.

JavaScript API

The browser helpers that wrap these endpoints.

Click data

Everything a click record holds.

Idempotency

Why retries need an external identifier.
Last modified on July 21, 2026