Payouts
A payout sends money from your available balance to any MTN or Airtel wallet (cash-out).
| Method | Path | |
|---|---|---|
| POST | /v1/payouts | Create a payout |
| GET | /v1/payouts/:id | Retrieve a payout |
| GET | /v1/payouts | List payouts |
The payout object
{
"id": "pyt_01J9Z4A1B2C3D4E5F6G7H8J9K0",
"object": "payout",
"status": "SUCCESSFUL",
"amount": "150000",
"currency": "UGX",
"country": "UG",
"network": "AIRTEL",
"msisdn_masked": "+2567****567",
"reference": "payout-seller-77-2026-09",
"fee": "2250",
"total_debited": "152250",
"provider": "…",
"approval_status": "NOT_REQUIRED",
"failure_code": null,
"failure_message": null,
"metadata": { "seller_id": "77" },
"created_at": "2026-09-28T10:00:00.000Z",
"updated_at": "2026-09-28T10:00:21.000Z"
}Attributes
idstring- Unique id, prefixed
pyt_. objectstring- Always
"payout". statusenum- See Transaction statuses.
amountstring- What the recipient receives, in full.
currencyenumUGX,KESorGHS.countryenum- The wallet's country:
UG,KEorGH. networkenumMTNorAIRTEL.msisdn_maskedstring- The wallet number, masked (
+2567****456). Full numbers are never returned. referencestring- Your reference, unchanged.
feestring- SkanPay's fee, charged on top.
"0"until the payout succeeds. total_debitedstringamount + fee: what leaves your balance. While the payout is in flightfeeis still"0", so this shows onlyamount, althoughamountplus the fee is already held.providerstring | null- An identifier for the rail that carried the payment. Informational: don't build logic on it.
approval_statusenum- Always
NOT_REQUIREDfor payouts today. failure_codestring | null- Why it failed. See failure codes.
failure_messagestring | null- Human-readable reason. Don't parse it.
metadataobject | null- As sent.
created_atstring- ISO 8601, UTC.
updated_atstring- ISO 8601, UTC. Changes with the status.
Create a payout
POST/v1/payouts
Holds amount + fee from your available balance and sends amount to the wallet. Rate-limited to 60 per minute. The outcome arrives as payout.successful or payout.failed; on failure the hold is returned in full.
Headers
Idempotency-KeyheaderRequired- 8–255 characters. Same key and body returns the original response. See Idempotency.
Body parameters
amountstringRequired- Integer minor units as a string, e.g.
"50000". See Amounts. currencyenumRequiredUGX,KESorGHS. Must be the currency of the wallet's country.msisdnstringRequired- The recipient's phone number. International format (
+256772123456) is safest; local formats are read againstcountryor your account's country. See Phone numbers. referencestringRequired- Your own id for this payment, e.g. your order id. 1–128 characters from
A–Z a–z 0–9 . _ : -. Returned unchanged everywhere. networkenumOptionalMTNorAIRTEL. Worked out from the number; send it only when you getnetwork_required, or when you already know it. It always wins over the prefix table.countryenumOptionalUG,KEorGH. Read from the number's dialing code; used only to interpret a number in local format. Defaults to your account's country.narrationstringOptional- Up to 100 characters. Shown to the recipient where the network supports it.
metadataobjectOptional- Up to 20 keys of your own data. Values are strings (≤ 512 characters), numbers, booleans or
null.
curl -X POST https://api.skanpay.website/v1/payouts \
-H "Authorization: Bearer $SKANPAY_SECRET_KEY" \
-H "Idempotency-Key: payout-seller-77-2026-09" \
-H "Content-Type: application/json" \
-d '{"amount":"150000","currency":"UGX","msisdn":"+256701234567","reference":"payout-seller-77-2026-09","narration":"September earnings"}'Errors specific to payouts: insufficient_balance, payouts_not_enabled_live, plus the phone-number, currency and limit errors shared with charges.
Retrieve a payout
GET/v1/payouts/:id
curl https://api.skanpay.website/v1/payouts/pyt_01J9Z4A1B2C3D4E5F6G7H8J9K0 \
-H "Authorization: Bearer $SKANPAY_SECRET_KEY"Returns the payout, or 404 payout_not_found.
List payouts
GET/v1/payouts
Same filters as charges, newest first, cursor-paginated.
Query parameters
statusenumOptional- One of the statuses.
referencestringOptional- Exact match on your reference.
countryenumOptionalUG,KE,GHnetworkenumOptionalMTN,AIRTELcreated_afterdatetimeOptional- ISO 8601, inclusive.
created_beforedatetimeOptional- ISO 8601, inclusive.
limitintegerOptional- 1–100, default 25.
starting_afterstringOptional- The
next_cursorof the previous page.
curl "https://api.skanpay.website/v1/payouts?status=FAILED" \
-H "Authorization: Bearer $SKANPAY_SECRET_KEY"