Skip to main content
The Affiliate REST API reports referred-user activity, progress toward CPA bounties, and your payout history. Authentication uses the same API key and secret as the rest of the Kraken REST API. For key setup, see REST Authentication. Requests sign each call and send api-key, api-sign, and api-nonce headers (the signed path includes the query string). When creating or editing your API key, select the Query affiliate participants checkbox and save the key. See API key setup. Schemas are in Get Daily Activity, Get CPA Progress, and Get Payout History. All examples use synthetic identifiers, not customer account data. Replace example dates with dates inside the current 90-day window.

Shared Python helper

CPA progress

Use the full IIBAN from Get Daily Activity to retrieve one referred trader’s progress. Each eligible bounty is returned separately with its reward, status, requirements, exact measurable values, and percentage.
A response can contain more than one bounty:
Qualified and paid bounties remain visible. A bounty can also be expired, no_longer_eligible, or not_tracked. When progress_availability is unavailable, measurements may be omitted. Unknown IIBANs, referrals belonging to another affiliate, and traders who opted out return 404. CPA progress summarizes the bounty lifecycle. It is not a one-to-one copy of the payment state in payout history. Use payout history to determine whether a payment is pending, on hold, or needs action. Before a payment record exists, reward_amount is an estimate calculated from the current plan amount, current conversion rate, and your affiliate share. It can change between calls. After a payment record exists, the API returns that record’s amount. Region-specific bounties that do not apply to the trader are omitted. The bounties collection can therefore be empty.

Payout history

Request your payout history without a cursor to start from the newest row. The response can include revshare, prop, cpa, and futures_accelerator_bonus sources.
summary covers all included RevShare, Prop, CPA, and Futures Accelerator Bonus payouts, not only the current page. It includes rows whose public status is paid or pending. Other statuses can appear in items, but do not contribute to the totals or Prop and CPA counts. Retainer, sub-affiliate carve-out, and remediation payouts are not included in this endpoint. When next_cursor is present, pass it unchanged with the same page size. Stop when it is absent:

Daily activity

Both variants are signed with your own API key. Dates are UTC calendar days (YYYY-MM-DD) and must be today or one of the previous 89 UTC days. A future date or a date older than that window is a 400. A valid day with no matching activity or enrollments is an empty page, not an error.

By day

Give a trade date. You get referred users with reportable activity, plus quiet users who enrolled that day and are still enrolled. Opted-out users are omitted from this default listing; use the full roster or person history for existence stubs. Activity is split by plan and product, with day-wide totals. A user who has never traded still has an enrollment-day entry with enrolled_at and empty products; this confirms enrollment, not trading activity.
For a request with activity_date=2026-09-15, this enrollment-day item confirms a signup before any trading. On September 16, this user appears only in the full roster:
The enrollment time is in plans[].enrolled_at. Empty products may be omitted. This entry does not increase active_users.

Full referral roster

Add all_users=true to a day request to include quiet users enrolled in your affiliate plan by that date who are still enrolled, even if they signed up more than 90 days ago. Their products object is empty when they have no reportable activity that day. The requested activity date must still be within the last 90 UTC days.
With the Python helper, pass the query value as the lowercase string "true":
Follow next_cursor with the same date and all_users=true to retrieve the whole roster. active_users, totals, and revision continue to describe trading activity for the requested day; quiet users do not increase them. all_users is available only for day requests, not person history requests. This full-roster response includes a trading user, a quiet user, and an opted-out user. Only the trading user contributes to active_users and totals.

By person

Give up to ten full IIBANs (Kraken account identifiers) returned by this API or shared by the people you referred, plus an inclusive date range. You get per-day entries for those people, never a total for the whole range. Day-wide fields (totals, active_users, revision, estimated, opted_out) are omitted.
Empty, duplicate, or malformed IIBAN tokens are a 400. Validity is a format check only, not account existence. A valid IIBAN that does not match a referred user on your plan returns an empty result. An opted-out user who is still enrolled and enrolled by the end of the requested range returns one existence stub without activity_date. The stub does not reveal which days they traded. Visible history entries include the matching full iiban; opted-out stubs omit it. In this example, CC34N84GQK2VUN7C belongs to a user whose identifier you obtained before they opted out. The response contains dated activity for the trader and one undated stub for the opted-out user:
Sending both variants on one request is a 400.

Identifying a referred user

Use referee_reference to match a referred user across days. It is stable under your account, but it is not a Kraken account ID and cannot be matched across affiliate accounts. The same reference remains on an opted-out stub. iiban is the full Kraken account identifier for a referred user sharing activity. It is returned on daily, full-roster, and history entries, including quiet enrollments. You can use it in person-history requests. Opted-out stubs omit it. masked_iiban remains available for compatibility. It contains only the last four characters and is not unique; use iiban to match a Kraken account or referee_reference to track the enrollment. enrolled_at is truncated to the hour.

Products

One key per product that had activity. The map is open-ended: ignore unknown keys. For a visible activity entry, an absent key means no reported activity for that product. Empty products may be omitted. For an opted-out stub, empty or omitted products means data is withheld, not zero. Options is not included. maker and taker appear only on execution products, and only when that side had classified fills. When both are present they sum to the classified portion; the difference from the product total is unclassified. Absence means unclassified, not zero. Instant buy/sell and financing charges have no liquidity side. geo_blocked is present only when that product had blocked-region activity. Activity from blocked regions pays zero commission. The product’s volume, fees, event_count, and commission cover payable activity only; geo_blocked is shown separately and is not included in those product totals.

Totals, opt-out, and payments

Day-wide totals include activity from referred users who have not opted out. With all_users=true or person history, opted-out users appear in items as existence stubs:
The reference matches their visible entries before opt-out. enrolled_at is truncated to the hour. The plan’s referral_code preserves plan attribution; it does not expose the person’s account identifier. Stubs omit iiban, masked_iiban, individual amounts, campaign, plan status, and earning details. Treat opted_out=true as withheld data, never as zero activity. Stub presence does not depend on trading. Ordinary daily requests omit these stubs. People who are not enrolled in your plan are omitted from items, including on past dates, but stay in totals so past totals remain consistent. They are not counted in opted_out. Combined opted-out activity may appear under the response’s top-level opted_out:
  • { "suppressed": {} } when opted-out referees remain enrolled and zero or one has reportable activity
  • { "summary": { "active_participants", "products" } } when two or more have reportable activity
The top-level opted_out is omitted only when there are neither qualifying opted-out enrollments nor reportable opted-out activity. Suppression does not tell you whether anyone traded. This rule applies to both daily listings and full-roster requests. The existence of a stub does not imply inclusion in an activity summary. Payable for the day is totals plus summary when summary is present. Daily figures will not match weekly payments exactly:
  • Totals show activity eligible for commission
  • Geo-blocked activity is shown separately and pays zero
  • This API groups activity by trade date; weekly payments group it by when it was recorded

Staleness

A trade day’s figures can change when activity is reported later. revision (day variant, first page) is when your figures for that UTC day were last written. A later value on re-fetch means your figures moved. Another partner’s late event does not move this value. Re-check the trailing 35 days. Enrollments and sharing-setting changes do not advance revision. Refresh the roster even when revision has not changed to discover signups and opt-outs. When estimated is true on the first page, amounts for that calendar day are still an estimate, including the opted-out remainder.

Pagination

limit defaults to 50 and rejects values over 200. When next_cursor is present, pass it as cursor on the next request. Treat next_cursor as an opaque value: pass it as cursor without changing it. Keep the date or history range, identifiers, and all_users value unchanged. A daily cursor cannot be reused for a full-roster request, or vice versa. active_users, totals, revision, estimated, and opted_out are first-page only. An empty totals map on a later page is omission, not a zero day.

Errors

Empty collections and zero-valued fields may be omitted. Read missing items as [], missing products as {}, and missing first-page active_users as 0. For opted-out stubs, always use opted_out=true to distinguish withheld data from no reported activity. Successful bodies are the object itself. Errors are a non-2xx status with a typed error body. The helper raises KrakenApiError with the parsed body on failure. Throttling is covered in Rate limits.