Skip to main content
Resolving a referral is not instant. When the tracking script loads it has to read the URL, check storage, and often record a click over the network before it knows who referred the visitor. Two events tell you when that work is done, so your code does not have to poll window.affiliateId or guess at a delay. Use affiliate_id_ready when you need the attribution values. Use affiliate_referral_ready when you need to know that tracking has settled, whoever the visitor is.

Listen on window

Both events are dispatched on window. They do not bubble to document, so a listener attached to document never fires.

affiliate_id_ready

Fires as soon as the script has both a referral code and a click ID for the visitor. This is the moment window.affiliateId becomes trustworthy.
detail.ref
string
The referral code from the affiliate link — the value of ?ref=, or whichever parameter your program uses.
detail.clickId
string
The ID of the recorded click. This is the value you attach to a sale reported from your server.
It never fires for a visitor who arrived without a referral. If you have code that must run for every visitor, put it on affiliate_referral_ready instead and read the values there.

affiliate_referral_ready

A plain Event that signals “the script has finished deciding”. It carries no detail — read the state yourself once it arrives:
This is the event to hook when you want a single place to run your attribution wiring, because it fires on the no-referral path too, and even when recording the click failed.

When each event fires

The repeat-click row is the one that catches people out. When a visitor who already has a stored referral lands on the same link again, the script records an extra click and fires affiliate_id_ready, but affiliate_referral_ready is skipped. Anything that must run on every page load belongs in a listener for affiliate_id_ready and a fallback, not in affiliate_referral_ready alone.

Ordering and timing

affiliate_id_ready always fires first, then affiliate_referral_ready.
  • On the paths that need no network call — no referral, or a referral already in storage — affiliate_referral_ready is delayed by roughly 100 ms. That gap exists so code loaded alongside an async snippet still has time to attach its listener.
  • On a fresh click, affiliate_referral_ready fires immediately after the click is recorded, which can be several hundred milliseconds into the page depending on the network.
  • If the click request fails, affiliate_referral_ready still fires, and the stored referral is cleared first. Your listener will see null values.
Because the timing depends on the visitor, never assume the events have already fired, and never assume they have not.

Never miss the event

The safe pattern is to handle both orderings: check the current state once, and attach a listener for the case where the script has not finished yet.
Guard the callback against running twice if the work it does is not idempotent.

Cases where neither event fires

The script exits before dispatching anything when it cannot find a program to track against — that is, when the snippet has no data-program-id attribute and there is no programId query parameter on the URL. If your listeners never run, check the snippet first. Turning on debug mode prints the program ID the script resolved.

Names reserved by Referly

The tracking script listens for affiliate_referral_ready itself: that is how it decides whether to load your program’s popups and banners for a referred visitor. Do not dispatch either event yourself and do not reuse the names for your own events, or you will trigger Referly behaviour at the wrong moment.

JavaScript API reference

The functions the script exposes and how to call them.

Globals

The values the script puts on the window.

Attribution

How a click becomes a credited sale.

Debug mode

Watch the script’s decisions in the console.
Last modified on July 21, 2026