API referencePayoutsOverview

Payouts

Send money to recipients across NGN bank accounts, CAD Interac email IDs, and GBP / USD / EUR bank rails — one endpoint, POST /v1/payouts, with a currency-specific recipient block.

Each currency has its own integration page. A page is self-contained: if you only send GBP, you only need the GBP page.

CurrencyPageHow it routes
NGNNGN payoutsNigerian interbank rails (NIP), multi-provider cascade
GBPGBP payoutsInternational account rail (Faster Payments), backed by your GBP virtual account
USDUSD payoutsInternational account rail (ACH or wire), backed by your USD virtual account
EUREUR payoutsInternational account rail (SEPA), backed by your EUR virtual account
CADCAD payoutsInterac e-Transfer (email-routed — no bank account needed)

GBP / USD / EUR / CAD require international accounts to be enabled on your account. The GBP/USD/EUR send gate then depends on your flow (individual vs business): an individual sends from the sender’s own virtual account (sender_account_not_provisioned if missing), a business/treasury merchant sends from its own international account (no_active_international_account if missing). CAD routes via Interac for both. NGN works out of the box.

Two ways to specify the recipient

  1. beneficiary_id — reference a recipient you saved via POST /v1/beneficiaries. Swappr resolves the full recipient details server-side. Preferred for FX (GBP / USD / EUR / CAD): the saved beneficiary captures the address details the receiving network needs, so payouts settle reliably.
  2. Inline recipient — pass the recipient details on the payout itself. Standard for NGN. Still supported for FX, but soft-deprecated — prefer beneficiary_id for new FX integrations.

When beneficiary_id is set, any inline recipient is ignored.

Common fields (all currencies)

FieldTypeRequiredNotes
amount_minorstring (BigInt)yesMinor units — kobo for NGN, cents for USD/EUR, pence for GBP, cents for CAD. Never a float.
currencystringyesNGN | GBP | USD | EUR | CAD
recipientobjectconditionalInline recipient (currency-specific). Required unless beneficiary_id is supplied.
beneficiary_idstringconditionalSaved beneficiary reference. Alternative to recipient. Must match the payout currency.
wallet_idstringnoAuto-resolved from currency + env if omitted.
merchant_referencestringnoYour own ref. Unique per merchant in a 30-day window.
narrationstringnoDescription shown on the recipient’s statement (NGN).
customer_idstringnoSender attribution — your end-user customer id (see Customers). Surfaces in payout.* webhooks, GET responses, and the customer’s transaction history.
customer_referencestringnoOpaque attribution string (max 64 chars), echoed in webhooks + GETs.
sender_customer_idstringconditionalFX sender id — required for CAD / GBP / USD / EUR unless a full inline sender block is supplied. See sender attribution.
senderobjectconditionalInline sender identity for compliance. See sender attribution.
allow_duplicatebooleannoBypass the beneficiary cool-down for an intentional retry.

The Idempotency-Key header is required on POST /v1/payouts. Same key + same body returns the cached response; same key + different body returns 409.

Customer attribution

customer_id + customer_reference link a payout to one of your end-user customers. Once set, the values appear in payout.* webhooks, the payout’s GET response, and the unified GET /v1/customers/{id}/transactions feed — so you can rebuild a customer’s history without storing every event yourself. Both are optional and work on every currency.

Sender attribution (FX)

For FX currencies (CAD / GBP / USD / EUR) the sending customer must be identified for compliance. You can do this two ways, and they are complementary, not mutually exclusive:

  • sender_customer_id — reference a customer you created via POST /v1/customers. Swappr resolves their stored KYC to satisfy the sender-info requirement, and uses it for attribution.
  • sender block — the sender’s identity inline (name, ID type/number, date of birth, country).

If you pass both, the inline sender fields take precedence per-field and the referenced customer’s stored KYC backfills any fields you omit. If you pass customer_id as well, it must match sender_customer_id (both reference the sending customer) or the request is rejected with customer_id_mismatch.

Common error codes

CodeHTTPCause
missing_field400Required body field absent
invalid_field422Wrong type / format
wallet_not_found422wallet_id doesn’t match merchant + currency + env
unsupported_currency422Currency not active for this merchant
beneficiary_not_found404beneficiary_id unknown / not yours / wrong env
beneficiary_currency_mismatch400beneficiary_id currency ≠ payout currency
fx_features_not_enabled403International accounts not enabled for this merchant (FX currencies)
no_active_international_account403(Business/treasury flow) No active merchant international account for this currency
sender_account_not_provisioned422(Individual flow) The sending customer has no active virtual account in this currency — issue one via POST /v1/customers/{id}/virtual_accounts
customer_not_found404customer_id unknown / not yours
customer_id_mismatch400customer_idsender_customer_id on an FX payout
env_mismatch409customer_id belongs to the other environment
sender_info_required422Account requires sender info; supply sender or sender_customer_id
idempotency_key_conflict409Same Idempotency-Key, different body
provider_error502Downstream rail unreachable; safe to retry with the same key

Per-currency pages list the extra codes specific to each rail.

Base URL

All examples use the production base URL — the environment is selected by your secret-key prefix (sk_test_… vs sk_live_…):

https://api.swappr.me/api/v1

Manage payouts

POST /v1/payouts creation is documented per currency. The management endpoints below are currency-agnostic:

  • GET /v1/payouts — list (cursor-paginated; filter by status / currency / date).
  • GET /v1/payouts/{id} — retrieve (accepts the cuid or the po_… reference).
  • POST /v1/payouts/{id}/requery — force a provider status refresh for a stuck processing payout.
  • POST /v1/payouts/{id}/cancel — cancel a draft or queued payout.

See any per-currency page for the full payout object, status values, and the management-endpoint details.