Documentation
Concepts

Attribution

How each payment gets the channel that introduced the customer and the one that closed them.

Every payment gets two answers, not one:

  • Introduced by — the earliest qualifying touch inside the window. This is who found the customer.
  • Closed by — the latest qualifying touch before the money. This is who finished the job.

A blog post that brought someone in six weeks ago and an ad they clicked yesterday both did work. One number would hide one of them.

What counts as a touch

A touch is a human $session_start, $pageview, or $screen that carries a real source: a non-direct channel, or any ad click ID.

  • A visit with no campaign and no referrer is not a qualifying touch.
  • Bot visits never count. See Bot traffic policy.
  • If no qualifying touch exists in the window, the payment is Direct. FounderHQ never promotes a random visit to fill the gap, and Direct never erases a known earlier source.

The window

The window is counted back from the day the money was earned, not the day the webhook arrived. That keeps a renewal on the renewal's own merits. The default is 90 days. You can also use 30, 60, or 180. Each result records the model and the window that produced it, so two reports never disagree silently.

Where the source comes from

The SDK reads campaign parameters and ad click IDs from the URL on every landing, then keeps both the first and the latest value on the contact. There are 24 keys: the five utm_* parameters plus 19 click IDs from Google, Meta, Microsoft, LinkedIn, TikTok, Reddit, and others. The full list is in the event taxonomy. Mobile deep links and the Play install referrer feed the same keys.

Keep the chain through checkout

The gap most products lose is checkout. Attach the visitor's IDs to the payment so the payment can find the person.

const metadata = founderhq.checkoutMetadata();
// pass metadata into your Stripe or Dodo checkout session

Renewals do not carry that metadata, so FounderHQ also remembers the provider customer once matched. See Checkout metadata and payment links.

If a payment cannot be matched to anyone, it is parked rather than guessed, with candidate matches for you to confirm.

When facts arrive late

A touch that shows up after a decision was made does not quietly rewrite history. The decision is recomputed on request, and the new answer is added as a new version, so a number you screenshotted last week still explains itself.

AI agent or LLM? Read this page as markdown

On this page