externalReference, source account, destination, amount, and currency together.
1. Create a destination
For an own-account transfer:expiresAt has passed.
For an external payout, first call GET /v1/transfer-corridors?currency=KES&country=KE. Render the returned field descriptors, then either create an inline destination or save a recipient and payment detail for reuse. Provider selection stays internal to Sakawave.
2. Create an FX quote when needed
Skip this step when source and destination currencies match. Otherwise, send exactly one ofsourceAmount or destinationAmount, matching amountSide.
expiresAt. Supply its id as fxQuoteId when previewing and creating the matching transfer.
3. Preview fees and total debit
fee, totalDebit, currencies, and destination with your user before creating the transfer. Request amounts use minor units; preview amounts are returned as decimal strings.
4. Create the transfer
externalReference returns the existing transfer. It does not validate that a later payload matches the original, so never reuse a reference for a different payment.
5. Handle the lifecycle
API keys can initiate transfers but cannot approve or reject them. Handle statuses as follows:awaiting_approval: a human approver must act through an approved non-API-key flow.submitting: transient; poll with backoff if necessary. This status is not published as a webhook event.pending: accepted but not final.completed: final success unless a later reversal occurs.failed,rejected,reversed: do not mark paid; inspectfailureCodeandfailureReason.