Rekomi Docs
For brandsInstall tracking
Brands

Install on Ghost

Ghost Members bills through your own Stripe account, so a connected Stripe records every sale automatically. The head script in Code Injection captures the click, and a one-line lead capture on your signup form names the affiliate.

Ghost logo

Ghost Members uses your own Stripe account for paid memberships, so sales flow through the same Stripe rail as a native Stripe customer. The install is two pastes in Ghost's Code Injection: the head script for click capture, and a one-line lead capture on your signup form so Rekomi knows which affiliate sent the member. The only extra wrinkle is distinguishing free signups (no Stripe involvement, no commission) from paid upgrades (Stripe fires customer.subscription.created); Ghost's own webhooks fire member.added for both.

Install the head script

Step 1. In Ghost admin, navigate to Settings > Code injection > Site Header.

Step 2. Paste the Rekomi head script:

<script async src="https://api.rekomi.com/api/v1/r/loader.js" data-program-id="YOUR_PROGRAM_ID"></script>
<noscript>
  <img src="https://api.rekomi.com/api/v1/r/c.gif" width="1" height="1" alt="" referrerpolicy="no-referrer-when-downgrade" />
</noscript>

Save. The script loads on every public Ghost page (posts, pages, members portal entry). Code Injection is theme-agnostic, so it survives theme updates.

Your program ID is pre-filled into the snippet in Rekomi under Setup > Install (choose Ghost). The install works identically on Ghost Pro and self-hosted Ghost.

How attribution works (the standard path)

Ghost Members bills on your own Stripe account. When a visitor signs up for a paid tier, Ghost creates a Stripe Customer and subscription; Stripe fires customer.subscription.created and invoice.paid to Rekomi's webhook listener, and the sale records automatically.

Naming the affiliate takes one more step. Ghost's checkout cannot carry Rekomi metadata and its Members checkout has no coupon field, so Rekomi attributes the sale by matching the buyer's email against a lead recorded in the last 90 days. Record that lead at signup:

If your theme has an inline signup form (most Ghost themes wire these with data-members-form), add this once under Settings > Code injection > Site Footer:

<script>
  document.addEventListener("submit", function (e) {
    var form = e.target.closest ? e.target.closest("[data-members-form]") : null;
    if (!form || !window.Rekomi) return;
    var input = form.querySelector('input[type="email"]');
    if (input && input.value) window.Rekomi.convert({ email: input.value });
  }, true);
</script>

If members can only sign up through the Portal modal (the floating subscribe button), the head script cannot see inside it: the Portal renders in its own iframe. Point affiliate links at a landing page with an inline signup form instead, so the email is captured before the Portal takes over.

With the lead recorded, the paid upgrade attributes automatically when Stripe reports the sale, whether the member upgrades the same day or weeks later (within the 90-day lead window). Returning customers who were attributed once keep crediting the same affiliate on later invoices with no further capture.

Optional: backup conversion paths

The Stripe webhook is canonical and needs no extra setup. For billing modes that do not route through your Stripe account, use one of these instead of a page snippet. They are alternatives to the Stripe rail, not a parallel copy: the S2S endpoint is disabled while Stripe Connect is linked, to prevent the same sale being counted twice.

Coupon codes (no code). Coupon codes apply when your paywall checkout accepts Stripe promotion codes AND runs on the same Stripe account you connected to Rekomi (a third-party paywall or custom Stripe checkout); Ghost's native Members checkout has no code entry field, so rely on the lead-capture path there. Create per-affiliate coupon codes under Campaign > Coupons; when a buyer redeems an affiliate's code at a code-capable checkout, Rekomi credits that affiliate.

Server-to-server relay. Listen for Ghost's member.added webhook (it fires for every signup, free or paid, so filter to members with a paid subscription), then POST the sale to Rekomi's S2S tracking endpoint with HMAC from your backend. One requirement to plan for: the S2S payload names the affiliate by slug, and your server only knows the slug if your signup flow stored it (for example, a custom signup that saves window.Rekomi.getReferral() on the member). This carries the real order amount without depending on the browser.

Free vs paid distinction

Ghost's webhooks fire member.added for every signup, free or paid; only paid signups produce Stripe events and revenue, so use your Stripe webhook as the conversion source:

  • Free-tier signups: Ghost fires member.added, but there is no Stripe involvement and no commission on a sale-based program.
  • Paid signups: Stripe fires the canonical webhook (customer.subscription.created, invoice.paid); Rekomi records the sale and credits the affiliate matched from the signup lead.

If you run a lead-based program where the commission is on the email capture rather than a paid upgrade, that is a separate feature: see Lead tracking. Most affiliate programs commission on paid sales only.

Quirks worth knowing

Members API has rate limits. If you are syncing members programmatically via Ghost Admin API (e.g., to track free signups), Ghost throttles bursts aggressively. Use Stripe webhooks as the canonical conversion source; treat Ghost Admin API as enrichment, not the source of truth.

Ghost's theme context has no "amount just paid". Themes can list tier prices (the {{#get "tiers"}} helper), but there is no per-member charge amount available on a post-signup page, which is one reason the sale is recorded through Stripe (or a server-side relay) rather than the page. If you use the server-to-server backup, read the amount from the member payload of Ghost's member.added webhook or from Stripe, not from the theme.

Theme updates and Code Injection. Ghost's Code Injection > Site Header is independent of theme files, so switching themes preserves the head install. Nothing else needs re-adding after a theme switch.

Self-hosted Ghost is identical. The same Code Injection field exists on self-hosted Ghost. No differences in install behavior between Ghost Pro and self-hosted.

Refunds

When you refund a payment, Stripe fires charge.refunded and Rekomi reverses the commission and updates the affiliate's pending balance automatically. A cancellation (customer.subscription.deleted) is different: it stops future renewal commissions but does not claw back commission already earned. No Ghost-side configuration needed for either.

If you are on a non-Stripe billing mode (rare for Ghost), refund attribution requires forwarding Ghost's member cancellation webhook to /api/tracking/refund with the matching externalEventId from the original conversion.

Troubleshooting

Visitor signs up for paid, no conversion lands in Rekomi. Confirm Stripe is connected under Setup > Connect payment gateway in Rekomi, then check the Sales page: if the sale is there but shows no affiliate, the lead-capture step is missing (see "How attribution works" above); if the sale is missing entirely, the Stripe connection is the problem.

Visitor signs up for free, no conversion lands. Expected. Free signups do not generate Stripe events and are not commissioned by default. If you want to commission free signups, see "Free vs paid distinction" above.

Signups through the Portal modal never attribute. The Portal renders in its own iframe, which the head script cannot see into, so the member's email never reaches Rekomi as a lead. Use an inline signup form (a data-members-form form in your theme) on the pages affiliates link to, with the footer snippet from "How attribution works" capturing the email.

Refund did not clawback. Confirm the refund actually ran in Stripe (a canceled subscription alone does not refund anything). If the refund is there and the commission still stands after a few minutes, check the activity log in Rekomi for the corresponding entry and contact support if it never arrives.