API reference
Payouts
Preview and disburse matured commission.
Preview pending payouts
GET
/v1/programs/:programId/payouts/pendingread scopeShows what a dispatch would send, grouped by affiliate — plus everyone who is blocked and why.
Path parameters
| programIdrequuid | From `GET /v1/me`. |
Response
json
{
"payable": [
{ "affiliateId": "c41a...", "name": "Kristin Richards", "commissionCents": 184200, "conversionCount": 37 }
],
"blocked": [
{ "affiliateId": "b12f...", "name": "Sam Doe", "commissionCents": 2400, "blockedReason": "below_minimum_payout" }
],
"totalPayableCents": 184200,
"minimumPayoutCents": 5000,
"payoutProvider": "stripe_connect"
}- `blockedReason` is one of `affiliate_not_active`, `missing_tax_info`, `payout_account_not_connected`, `below_minimum_payout`.
- Only conversions past their holding period are counted.
Dispatch a payout batch
POST
/v1/programs/:programId/payouts/dispatch-batchwrite scopePays every eligible affiliate through the program's configured payout provider.
Path parameters
| programIdrequuid | From `GET /v1/me`. |
Response
json
{
"batchId": "e77c...",
"succeededCount": 12,
"failedCount": 0,
"skippedCount": 3,
"totalAmountCents": 942100
}- **This moves real money and is not request-idempotent.** Paid conversions flip to `paid` and are excluded from the next batch, so a retry pays only what genuinely didn't go out — but two concurrent calls can create two batches.
- Preview with `payouts/pending` first.
- Returns `422` when there is nothing to pay. That is a valid state, not a failure — don't alert on it.