PilotFoxDocs

Affiliate portal

Share a read-only portal with each affiliate, and read an affiliate's own numbers with its portal token.

Each registered affiliate can get a portal: a page that needs no PilotFox account and shows that affiliate's own numbers. You share it as a link; behind it, the portal reads GET /api/v1/affiliate-portal with the link's token.

On an affiliate's page, Create portal link makes a link of the form https://pilotfox.app/a/<token> (a self-hosted instance uses its own PUBLIC_URL).

  • The link is shown once: PilotFox keeps only a SHA-256 hash of its token (32 random bytes).
  • Regenerate link makes a new one; the previous link stops working at once.
  • Revoke turns the portal off. Deleting the affiliate or the site turns it off too.
  • Creating a link needs affiliates:write and revenue:read on the site, because the portal shows revenue and commission: nobody can hand out more than they can see (403 otherwise). Revoking needs affiliates:write only.

The same over the API:

# Create (or regenerate) the portal link: 201 with the token and the link, shown once.
curl -X POST "https://pilotfox.app/api/v1/sites/SITE_ID/affiliates/AFFILIATE_ID/share" \
  -H "Authorization: Bearer $PILOTFOX_API_KEY"

# Revoke it: 204.
curl -X DELETE "https://pilotfox.app/api/v1/sites/SITE_ID/affiliates/AFFILIATE_ID/share" \
  -H "Authorization: Bearer $PILOTFOX_API_KEY"
201 Created
{ "data": { "token": "AFFILIATE_TOKEN", "url": "https://pilotfox.app/a/AFFILIATE_TOKEN" } }

An affiliate's shareEnabled says whether it has a portal link.

Treat the link like a password: anyone who has it can open the portal. Send it to the affiliate only, and regenerate it if it leaks.

What the portal shows

The affiliate's name, commission rate and referral link, the site's name and domain, and for the last 7, 30 or 90 days (in the web page) their visits, visitors, payments, revenue and commission, with a chart over time and their top landing pages. It shows totals only: never individual visitors, payments, referrers or emails. Money is in the site's default currency.

Read the portal's numbers

GET /api/v1/affiliate-portal is public: its only credential is the token, sent in the x-affiliate-token header (never a cookie, a query parameter or a path segment; the header is kept out of the server's logs).

curl "https://pilotfox.app/api/v1/affiliate-portal?last=7d" \
  -H "x-affiliate-token: $AFFILIATE_TOKEN"
200 OK (shortened)
{
  "data": {
    "affiliate": { "name": "Jane Doe", "slug": "jane", "commission_percent": 20 },
    "site": { "name": "Docs shop", "domain": "shop.example.com" },
    "link": "https://shop.example.com/?ref=jane",
    "currency": "usd",
    "totals": { "visits": 1, "visitors": 1, "payments": 8, "revenue": 25800, "commission": 5160, "conversion_rate": 200 },
    "series": [{ "t": "2026-10-21T00:00:00.000Z", "visits": 0, "visitors": 0, "payments": 0, "revenue": 0 }],
    "landing_pages": [{ "pathname": "/pricing", "visits": 1 }]
  },
  "meta": { "window": { "from": "2026-10-20T20:31:19.327Z", "to": "2026-10-27T20:31:19.327Z", "tz": "UTC", "bucket": "day" } }
}
  • The window parameters are the usual ones (last=7d, start/end, …); without any, the last 30 days. Amounts are in the currency's smallest unit; the figures are the same as in the dashboard.
  • A missing token, or one that is unknown, revoked, or of a deleted affiliate or site, is 401.
  • Refused tokens count against the client's budget of refused credentials, shared with share-link tokens and API keys: once it is spent, requests are 429 for a while.
  • Each client may make 60 portal requests a minute.

See the reference page for every field.

On this page