The commission ledger
How commission events form an append-only ledger, how balances are derived from it, and how to approve and correct lines.
Every commission is a sequence of immutable events. Nothing is ever edited or deleted: a refund adds a negative event, a manual fix adds an adjustment, a payout adds a paid event. Balances are computed from these events on every read, so the numbers always trace back to the facts that produced them.
Event types
| Created by | Amount |
|---|---|---|
| A qualifying payment, a signup or trial bounty, or a sub-affiliate share. This is the line the other events refer to. | Positive. |
| A refund or dispute on the paying invoice. | Negative. |
| A manual correction. | Either sign. |
| Approval after the hold elapsed. | Snapshot of the line's net amount at approval. |
| A payout that settled, or a merchant settlement. | The line's net amount. |
All events except earned carry relatedCommissionId, the id of the line they refer to.
A line's net is its earned amount plus all of its reversed and adjusted events.
Line states
State | Condition |
|---|---|
| No |
| Has an |
| Has a |
Read the ledger
curl "https://referalli.com/v1/commissions?partnerId=ptr_...&type=earned" \
-H "Authorization: Bearer $KEY"Filters: partnerId, programId, type, referralId. Newest first and paginated (the latest 500 under 2026-10-21). Each has id, programId, partnerId, referralId, type, amountMinor, currency, relatedCommissionId, holdUntil, level (0 for the direct partner, 1 to 5 for sub-affiliate lines), memo and ts.
Read one event with GET /v1/commissions/{id} (404 if unknown). For an earned line, the response also has billingEventId, netMinor (the amount after reversals and adjustments), state (pending, approved or paid, as in Line states) and events: every event recorded against the line, oldest first.
Balances
curl https://referalli.com/v1/partners/ptr_.../balances \
-H "Authorization: Bearer $KEY"[
{ "currency": "usd", "pending": 1980, "approved": 4500, "paid": 12000, "reversed": 990 }
]One row per currency. pending, approved and paid are the sums of line nets in each state. reversed is the total clawed back, shown for information; it is already subtracted from the other three.
The invariant
For every partner and currency:
sum(earned + adjusted + reversed events) == pending + approved + paidApproved and paid events never change the total; they only move a line between states. Referalli's own test suite asserts this invariant across billing edge cases. If you mirror the ledger in your own system, check it the same way from GET /v1/commissions (under referally-version: 2026-11-01 it pages with no cap, see Pagination; under 2026-10-21 a call returns at most the latest 500 events).
Approve lines after the hold
Each earned line has a holdUntil timestamp: the payment (or signup, or trial start) time plus the rule's holdDays. Lines are not approved automatically, except just before a scheduled payout run, which approves them for you. Approve every line whose hold has passed with:
curl -X POST https://referalli.com/v1/commissions/approve-due \
-H "Authorization: Bearer $KEY"
# { "approved": 37 }Run it on your own schedule, for example daily, or just before creating a payout run. It requires the owner, admin or finance role and is safe to repeat: lines already approved are skipped.
Correct a line
curl -X POST https://referalli.com/v1/commissions/cme_.../adjust \
-H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{"amountMinor": -500, "memo": "goodwill credit reclaimed"}'
# { "id": "cme_..." }amountMinor is an integer of either sign, and memo is required. The id in the path must be an earned line. The adjustment changes the line's net and therefore the partner's balance.
An adjustment that would take the line's net below zero fails with 400 and a message stating the current net, so running a cleanup script twice can't over-correct a line. To go below zero on purpose, send "allowNegative": true.
Refunds and disputes create reversed events automatically and emit commission.reversed. A refund reverses each line in proportion to the refunded share of the invoice, never more than the line's remaining net.
Settle a line yourself
When you pay a partner outside Referalli, for example as credit on their account with you, record it so the ledger shows it as paid:
curl -X POST https://referalli.com/v1/commissions/cme_.../settle \
-H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{"method": "store_credit", "reference": "ledger_tx_8812"}'{
"commissionId": "cme_...",
"paidEventId": "cme_...",
"partnerId": "ptr_...",
"programId": "prg_...",
"amountMinor": 200,
"currency": "usd",
"method": "store_credit",
"reference": "ledger_tx_8812",
"status": "paid"
}One call records
approved(if the line isn't approved yet) andpaid, for the line's current net. The hold doesn't apply, because you decide when you paid.referenceis your own id for the credit, up to 256 characters. Settling the same line with the samereferenceagain returns the original settlement and records nothing new. A differentreferencefor a line that is already paid returns409, and so does areferencealready used for another line.No payout, payout profile or tax form is involved. Store credit isn't cash, so it never appears in a payout run or the 1099 export.
It returns
409while the line is in an unfinished payout, or when the partner is suspended or blocked.It needs the
owner,adminorfinancerole, is audited, and emitscommission.settledwithcommissionId,partnerId,programId,referralId,amountMinor,currency,methodandreference.
Settle every line automatically
Set the program's settlement to merchant_credit and every line is settled the moment it is earned:
curl -X PATCH https://referalli.com/v1/programs/prg_... \
-H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{"settlement": "merchant_credit"}'Each line then gets its paid event straight away, with method: "merchant_credit" and the line's own id as reference, and commission.settled tells you to credit the partner. A suspended partner's lines aren't settled automatically; they wait as usual, and you can settle them by hand once the partner is active again. A later refund still reverses the line and emits commission.reversed, so debit the credit you gave. The default settlement is payout.