AffiliateTracking docs
The AffiliateTracking docs on one page: how to start on cloud or your own server, connect your site and billing, and use the API. Pick where you are.
Cloud
Start on cloud
We run it for you at yourbrand.affiliatetracking.co. Settings holds everything below.
Sign up and pick an address
Choose a plan and a workspace name. The trial runs 14 days. We charge your card when it ends, unless you cancel first.
-
Add the tracking script
Settings shows the tag with your address filled in. Paste it on every page of your site, right before </head>.
<script src="https://yourbrand.affiliatetracking.co/t.js" async></script>
Connect your billing tool
Stripe takes one restricted key. The others take a webhook address and a secret. The billing section below has each one.
Add affiliates
Approve applications in the Admin tab, or import your affiliates from Rewardful, FirstPromoter, Tolt or Tapfiliate.
Start on your own server
Self-host is one file with SQLite built in. Run it, make an admin key, and tell it which domains links may send people to.
Flags go before the command. Want Postgres instead? Pass a postgres:// address to -db and run migrate first. The full self-host guide covers servers, backups and proxies.
# 1. Start it (creates the database) ./affiliate-engine -listen :8080 -db sqlite:affiliate-engine.db # 2. Make an admin key. It's shown once ./affiliate-engine -db sqlite:affiliate-engine.db \ keygen -scope admin -name ops # 3. Where links may go, and your address AE_ALLOWED_DEST="yoursite.com" AE_PUBLIC_URL="https://track.yoursite.com" # Health check curl https://track.yoursite.com/healthz
Connect your site
Tracking links record the click. The script keeps the token on your domain until checkout.
Tracking links
Every affiliate link goes through /r/ and lands on an allowed page with a signed token.
https://yourbrand.affiliatetracking.co/r/jane ?dest=https://yoursite.com/pricing &subid=newsletter&utm_source=youtube
subid, utm_source and placement get their own columns in the affiliate's stats.
The script, t.js
It saves the token in a first-party cookie called at_token, then removes it from the address bar. The cookie lasts your attribution window: 30 days by default, 1 to 365.
// In the browser AffiliateTracking.token() // the raw token AffiliateTracking.clientReferenceId() // at1_... for Stripe
Moving from another tool? data-param="via" (or fpr, or ref) keeps old links working.
Connect billing
Each billing tool sends events to its own address. Each has a full setup guide.
| Billing tool | Webhook address | Self-host settings | Setup guide |
|---|---|---|---|
| Stripe | /webhooks/stripe | AE_STRIPE_SECRET (whsec_) | Stripe guide |
| Paddle | /webhooks/paddle | AE_PADDLE_SECRET | Paddle guide |
| Lemon Squeezy | /webhooks/lemonsqueezy | AE_LEMONSQUEEZY_SECRET | Lemon Squeezy guide |
| Chargebee | /webhooks/chargebee | AE_CHARGEBEE_USERNAME, AE_CHARGEBEE_PASSWORD | Chargebee guide |
| Recurly | /webhooks/recurly | AE_RECURLY_USERNAME, AE_RECURLY_PASSWORD, AE_RECURLY_API_KEY | Recurly guide |
REST API
36 routes: 26 for admins, 5 for affiliates and 5 public. Everything is JSON under /api/v1.
Keys and limits
Send a key as a bearer token. Admin keys see everything. Affiliate keys see one affiliate. Keys start ae_, and we only store a hash.
curl https://yourbrand.affiliatetracking.co/api/v1/admin/dashboard \ -H "Authorization: Bearer ae_..."
Limits: 600 requests a minute per key. After 30 failed tries a minute from one IP, it answers 429.
Affiliate and public routes
GET /affiliate/earningsTotals, 30-day stats and the ledger proofGET /affiliate/ledgerJournals, page by pageGET /affiliate/stats/drillBy subid, utm_source or placementGET /affiliate/uniquesDaily unique visitorsGET /affiliate/profileLevel and badgesPOST /portal/applyApply to a programPOST /portal/login,/portal/logoutPortal sessionsGET /leaderboard,/portal/brandPublic program info
Admin routes, under /api/v1/admin
GET dashboardGET, POST campaignsGET, POST rulesGET, POST, DELETE tiersGET, PUT branding
GET affiliatesPATCH affiliates/{id}GET, POST, DELETE codesGET portal/applicationsPOST portal/review
GET fraud/queuePOST fraud/resolvePOST payouts/runPOST payouts/approveGET, POST taxdocs
POST usagePOST mlm/runPOST mlm/place
Command line
Self-host only. The pattern is affiliate-engine [-db address] [-listen addr] command. With no command, it serves.
| Command | What it does |
|---|---|
keygen -scope admin -name ops | Makes an API key. Use -scope affiliate -affiliate 42 for one affiliate. |
doctor | Runs 6 integrity checks. Exits 1 if the money doesn't add up. SQLite. |
backup [out.db] | Copies the database while it runs. SQLite. |
restore -from backup.db | Checks the backup, then swaps it in. SQLite. |
migrate | Sets up or updates the database. Run it first on Postgres. |
import -from rewardful -csv f.csv --dry-run | Imports affiliates, codes and coupons. Also firstpromoter, tapfiliate or tolt. -rollback-batch ID undoes one. |
test-conversion -affiliate 42 | Pushes a test sale through the real engine, fraud checks included. |
gdpr-export, gdpr-erase | Exports or erases one affiliate's data. The books still balance. |
export-parquet -out dir | Writes your data as Parquet files for analysis. |
bench, version, help | Click benchmark, version and help. |
Settings
Self-host reads these environment variables. On cloud, we set the core ones for you.
| Variable | What it sets | Default |
|---|---|---|
| Core | ||
AE_ALLOWED_DEST | Domains links may send people to, separated by ; | example.com |
AE_PUBLIC_URL | Your public address. https also makes cookies Secure | From the request |
AE_TOKEN_SECRET | Signs tokens. At least 32 bytes | Made and saved on first start |
AE_SECRET_FILE | Where it keeps that generated secret | Next to the database |
AE_TRUSTED_PROXIES | Proxies allowed to pass the visitor's IP and country | None |
AE_COOKIE_SECURE | 1 sets Secure on every cookie | Off |
AE_REDIRECT_RATE_PER_MIN | Link clicks per IP per minute. -1 turns it off | 120 |
AE_MIGRATE_DATABASE_URL | Owner address for migrations, for a two-role Postgres setup | Unset |
| Stripe sales filter | ||
AE_STRIPE_PRODUCTS | Product, price or Payment Link IDs that earn commission | Every sale counts |
AE_STRIPE_API_KEY | Restricted key with Checkout Sessions read, for one-time checkouts | Unset |
| Fraud and privacy | ||
AE_FRAUD_DRYRUN | 1 scores sales without holding them | Off |
AE_IP_MODE | trunc24 drops the last part of each IP before hashing | off |
AE_CLICK_RETENTION_DAYS | Days before it deletes raw clicks. 0 keeps them | 90 |
| Other | ||
AE_DEMO | 1 runs a public read-only demo that resets daily | Off |
MCP and postbacks
Both come with self-host, and with the Business and Scale plans on cloud.
MCP server
Ask Claude, Cursor or any MCP client about your program. It reads, and never changes anything. Point your client at /mcp with an admin key as the bearer token.
Tools: earnings_summary, dashboard, fraud_queue, program_digest, usage_meter.
Postbacks
Send each sale to an affiliate's own tracker. Set a postback URL on the affiliate with PATCH /admin/affiliates/{id}. Failed calls retry up to 5 times.
https://tracker.example/pb?order={order_id}
&amount={commission_cents}&cur={currency}
# Every call carries a signature
X-AE-Signature: t=<unix>,v1=<HMAC-SHA256>
Stuck on a step?
Ask the people who built it.
Send your version, what you ran and what came back. The output of doctor helps too.