Concepts
The objects an affiliate program is made of, and the lifecycle a referral moves through.
Everything in AffiliateRail, in the dashboard, the API and the MCP server alike, is built from the same small set of objects. Ids are prefixed so you can always tell what you are holding: prg_ is a program, part_ a partner, com_ a commission, and so on. Money is always an integer amount in minor units (cents, pence) beside an explicit currency; rates are basis points, so 2000 means 20%.
The cast
Program (prg_). Your affiliate program: its currency, cookie window, commission defaults, portal branding and terms. An organization can run more than one.
Partner (part_). A person or company promoting you. A partner is pending (waiting for review), active, declined or suspended. Partners belong to at most one group and carry any number of tags.
Group. The commission and approval axis. A group is a tier of partner with its own terms: agencies at 30%, everyone else at 20%. Each group has its own signup link, so people land in the right tier on their own. Tags are the free second axis: labels for finding partners again, filtering, and targeting campaigns, notifications and resources. A tag never changes what a partner earns; that is what groups are for.
Link and coupon. A partner's ways in. A link is yoursite.com/?ref=handle, optionally also refer.yoursite.com/handle once you add a short-link domain. A coupon is a Stripe promotion code assigned to a partner, so sales using it attribute even without a click.
Click (clk_). One visit through a partner link. The click records the landing page and referrer, and carries the attribution window with it: how long it keeps the credit is written on the click when it happens, never recomputed later. The default window is 60 days, and the first touch wins within it.
Referral. The thread from visit to money: it starts as a visit, may become a lead, and becomes converted when the customer first pays. Partners see the same lifecycle in their portal, including how each referral was attributed, so they never have to take tracking on faith.
Customer (cus_). A referred customer, bound to the partner who referred them. Customers move through six explicit statuses: lead, trial, active, cancelled, refunded, suspended.
Sale (sale_). One payment, with amount, tax and currency. By default commission is calculated on revenue net of tax, so you never pay a percentage of VAT you collected for the tax office.
Commission (com_). What a sale earned a partner. Statuses: pending (waiting for approval), approved, due (matured and payable), paid, rejected, voided. Every commission records which flow and which branch produced it. A refund of an unpaid commission voids it; a refund of an already-paid one books a separate negative clawback against the partner's next balance, so the record of money that genuinely moved is never rewritten.
Flow (flw_). A commission rule: a trigger, an ordered list of branches (each a condition and a rate), and a fallback rate. Flows sort by priority, and the first flow that applies wins. Commission flows covers them properly.
Payout (pyt_) and payout batch. When a period closes, matured commissions net into one payout per partner per currency, sent on your NET term (15, 30 or 60 days after the period ends). A partner who cannot be paid is never silently dropped: the payout row exists as not_eligible with the reason (no payout method, missing tax form, balance under the minimum), on your side and theirs.
The lifecycle, end to end
- A visitor lands through
?ref=alice. The script records a click and sets the referral cookie. - They sign up. The referral becomes a lead; if you enrol them as a customer now, they are already bound to Alice.
- They pay. Stripe tells us; the sale is recorded, and the flow engine prices it into a commission for Alice, held for your holding period (14 days by default) as a refund buffer.
- You approve it, or your flow approves it automatically. Once matured it becomes due.
- The period closes, the NET term runs, and the commission lands in a payout paid from your own PayPal or Wise account.
Every step emits a webhook event, is queryable over the API, and is visible to the partner in their portal.
Live and test
Connect a test-mode Stripe account and the whole lifecycle runs on test data. API keys come in live and test flavours (rail_live_, rail_test_) against the same organization, and every API response says which mode it ran in. Nothing about attribution behaves differently in test mode.