Fees, referrals and combined claims
Let CRISP own attribution and payouts; render the configured program dynamically.
For the business model, start with Referral program: levels, configurable rates, treasury fallback and when rewards become payable. This guide implements that model. Fees and revenue explains the separate treasury payout flow.
Read the active program
Before you start: CRISP has enabled/configured your fee program. Use referral access for attribution, earnings and summaries, with claims enabled separately. Examples use the server client; HTTP tabs omit signing headers.
const result = await crisp.getFeeProgram();GET /v1/fee-program returns the effective program. Render its referral rules,
levels and rates dynamically; up to five levels are supported. Do not hardcode
example rates or another organization’s configuration. Fee changes create a new
version and do not rewrite policy already pinned to accepted orders.
Rates are basis points of eligible matched trading notional. 100 bps is 1% of that notional—not 1% of another fee. Buy/sell charge sides come from the program. The currently enforced total fee-program cap is 1,000 bps. CRISP approves commercial configuration and collection setup; dashboard owner/operators can manage permitted program settings. The HMAC API exposes the active program for reading, not a public arbitrary fee-program write route.
Attribute the direct referrer
Recommended for new integrations: include referrerExternalUserId in
createAccount. CRISP commits onboarding and the immutable edge together.
The referrer must already be registered under your organization in CRISP, but may still be provisioning. See
accounts. Existing integrations may keep the separate
endpoint below; it is still supported.
After both accounts exist and before first trade:
PUT /v1/accounts/{referredExternalUserId}/referrer
Idempotency-Key: referral-edge-unique-001{ "referrerExternalUserId": "example:referrer-123" }Supply only the direct referrer. CRISP checks that both accounts belong to your organization and rejects self-referrals and cycles and resolves the configured ancestors. Attribution is immutable; do not offer user-driven reparenting after joining. Capture referral links in your own product; authenticate eligibility before calling CRISP. The order records its ancestry and program at acceptance. Missing eligible ancestors follow the program's treasury fallback.
Earnings and history
For the user-facing balance and payout list, use the lifetime summary:
const result = await crisp.getReferralSummary('example:user-123', {
limit: 20,
offset: 0,
});summary contains exact decimal accruedUsdc, pendingSettlementUsdc,
claimableUsdc, payoutPendingUsdc and paidOutUsdc. These are lifetime amounts,
independent of chart dates and payout pagination. payouts contains one item per
payout ID, with its amount, state, transaction hash and covered UTC days. Use
hasMore to paginate; do not regroup or sum the same batch once per day.
Pending payout includes manual review and is not paid out.
Keep the earnings endpoint below for historical charts and per-level accrual. Its existing daily ledger fields and claim behavior have not changed.
GET /v1/accounts/{externalUserId}/referral-earnings?from=2026-09-01&to=2026-09-30&granularity=daily&limit=31Response data includes cadence, from, to, granularity,
earnings, series, levels, and claimEarnings. Dates are UTC; granularity is
daily/weekly/monthly; limit 1–366 (default 31), bounded date window. Use levels
for per-level earned amounts, not a hardcoded two-level UI. Historical reporting
windows do not expire older unpaid allocations.
- Accrued: earned allocations from eligible fills.
- Collected: collection from the trader into the fee collector; NOT referrer payout.
- Claimable: settled, reconciled and closed-day rewards eligible to claim.
- Paid out: a confirmed beneficiary payout, not mere request acceptance.
User-facing summaries can focus on accrued, claimable and paid out. Keep the internal collection distinction when reconciling. Current-day accrual is not immediately claimable; daily close may wait for collection/reconciliation.
One claim for all eligible days
const result = await crisp.claimAll(
'example:user-123',
'referral-claim-unique-001',
);Requires referral claims and settlement to be enabled. Your backend authorizes the logged-in beneficiary; do not let arbitrary users claim for another external ID. CRISP derives payout recipient from their managed wallet. The request accepts no user-supplied payout address or amount.
202 returns claims, aggregate amountUsdc and dayCount. All eligible days
are linked to one payout backing record and paid as one combined transfer.
Daily entries retain their amounts and may share one claim ID/transaction;
totalAmountUsdc is the batch total. Do not display or sum it once per day.
Show pending until the claim is confirmed; refresh earnings for payout state.
Done when: getReferralSummary reports a confirmed payout. claimAll
submits the request; it does not wait for payment. Preserve the claim intent and
refresh the lifetime summary if the response is lost. Do not use order-operation
polling for referral payouts.
Concurrent/duplicate requests cannot assign the same allocation twice. Still
disable duplicate UI submission and retain the original intent key. HTTP 409 with
referral_fee_nothing_claimable means no eligible unclaimed rewards remain.
Backing conflicts or historical rewards spanning collection wallets require CRISP
reconciliation; never tell users to bypass this by changing beneficiary/destination.
Compatibility { "feeDay": "YYYY-MM-DD" } claims remain available, but new UIs
should use { "all": true }, not a loop of daily claims. Do not send both fields.
Your treasury is separate
Your treasury receives payouts under the policy agreed with CRISP. This is separate from users claiming referral rewards into their managed wallets. Use the dashboard to review treasury income and payouts, and coordinate payout policy changes with CRISP. Program-wide collected totals include allocations that are not your revenue; show the net treasury share separately in operator reporting.
Exact contracts: getFeeProgram, getReferralSummary, claimReferralRewards.