Payouts

Send money to debit cards and bank accounts.

Payouts push money from your balance to a customer's debit card (rail: "card"), bank account via ACH (rail: "ach"), or bank account in real time (rail: "rtp"). Available on Paysio Debit & Payouts workspaces only — other workspaces receive a 400. Debit & Payouts is enabled per mode: a test (sk_test_) key can send payouts while a live (sk_live_) key returns "not enabled for this workspace in live mode", and vice versa — enable each mode separately in your dashboard. Amounts are fee-exclusive: the recipient receives the full amount and the payout fee is charged on top, so your balance drops by amount + fee. Payouts settle asynchronously — the create call returns "status": "pending" and the final state arrives via payout.paid / payout.failed webhooks.

Destination eligibility

Saved payment methods can only receive payouts when they are vaulted on Debit & Payouts — Stripe pm_ ids and NMI billing ids are rejected with a 400. Find eligible recipients with GET /customers?processor=aptpay, then pick a method with payout_eligible: true from GET /customers/:id/payment-methods. To pay out to a customer whose cards live on another gateway, collect a fresh card with paysio.createToken() (payment_token) or pass inline bank_account details — both work for any customer.

Create Payout

Create a payout. Provide exactly one destination: a saved payment method, a one-time card token from paysio.createToken(), or inline bank account details. The rail defaults to 'card' for card destinations and 'ach' for bank destinations.

POSThttps://paysio.com/api/v1/payouts

Authorizations

Authorizationstringheaderrequired

Secret key (sk_*). Prepend your key with Bearer, e.g. Bearer sk_test_your_secret_key.

Body

amountintegerrequired

Amount in cents the recipient receives (fee-exclusive — the payout fee is charged on top, so your balance is debited amount + fee)

customer_idstringrequired

The customer receiving the payout

currencystring

Currency code. Only "USD" is supported (default: USD)

payment_method_idstring

Saved card or bank-account method id from GET /customers/:id/payment-methods; use one with payout_eligible: true. A Paysio-vaulted id (vault_…) works regardless of the charging gateway — the Debit & Payouts instrument is minted on demand. Legacy Stripe pm_ ids and NMI billing ids are rejected with 400

payment_tokenstring

One-time ptok_ card token from paysio.createToken() — card destinations only. Works for any customer, regardless of which gateway their saved cards are on

bank_accountobject

Inline bank destination: { routing_number, account_number, account_type? ("checking" | "saving") }

railstring

"card", "ach", or "rtp". Default: "card" for card destinations, "ach" for bank destinations

rtp_networkstring

"TCH" or "FedNow" — only with rail "rtp". Use POST /account-checks to see which networks the bank supports

descriptorstring

Statement descriptor shown to the recipient (max 10 characters)

reference_idstring

Idempotency key. Reusing a reference_id returns 409 instead of creating a duplicate payout

metadataobject

Arbitrary key-value metadata. Filterable on GET /payouts via metadata[key]=value

send_emailboolean

Send the Paysio "money is on the way" email to the recipient. Default true. Set false to notify them yourself — nothing else changes.

List Payouts

List payouts, sorted by most recent. Sandbox-aware: test keys only see sandbox payouts.

GEThttps://paysio.com/api/v1/payouts

Authorizations

Authorizationstringheaderrequired

Any API key. Prepend your key with Bearer, e.g. Bearer sk_test_your_secret_key.

Query parameters

limitinteger

1-100, default 10

starting_afterstring

Cursor for pagination

customer_idstring

Only payouts to this customer

statusstring

Filter by status: pending, paid, failed, or canceled

metadata[key]string

Filter by metadata, e.g. metadata[invoice]=inv_123

Get Payout

Retrieve a single payout, including its current status, any failure details, and whether a settled payout was later returned by the receiving bank.

GEThttps://paysio.com/api/v1/payouts/:id

Authorizations

Authorizationstringheaderrequired

Any API key. Prepend your key with Bearer, e.g. Bearer sk_test_your_secret_key.

Get Balance

Get your current balance. 'available' is what you can pay out right now (ledger minus in-flight payouts); 'pending_payouts' is the total currently reserved by payouts that have not yet settled or failed.

GEThttps://paysio.com/api/v1/balance

Authorizations

Authorizationstringheaderrequired

Any API key. Prepend your key with Bearer, e.g. Bearer sk_test_your_secret_key.

Query parameters

currencystring

Currency code (default: USD)

Account Check

Pre-flight a payout destination. For cards: can it receive (and send) push-to-card funds, on which network, and how fast. For banks: which RTP networks (TCH / FedNow) the routing number supports. ACH has no pre-flight check — ineligibility surfaces as an ACH return after the fact.

POSThttps://paysio.com/api/v1/account-checks

Authorizations

Authorizationstringheaderrequired

Secret key (sk_*). Prepend your key with Bearer, e.g. Bearer sk_test_your_secret_key.

Body

payment_tokenstring

ptok_ card token from paysio.createToken() (card check)

customer_idstring

With payment_method_id: check a saved card (card check)

payment_method_idstring

Saved card payment method to check

cardobject

Raw card: { number, exp_month, exp_year } (card check)

bank_accountobject

{ routing_number } — 9 digits (bank check)

amountinteger

Amount in cents to test against card limits (default: 100)

currencystring

Currency code (default: USD)

Payout statuses

StatusMeaning
pendingAccepted and in transit. The amount is reserved against your balance.
paidSettled — the recipient has the funds. Fires payout.paid.
failedRejected by the network. The reserved amount is released back to your balance. Fires payout.failed with error_code and error_message.
canceledCanceled by the network before settlement. There is no API to cancel a payout yourself.

ACH returns

A settled ACH payout can still come back days later. The receiving bank rejects it with a NACHA return code — R03 (no account found), R02 (account closed), R04 (invalid account number), and the rest — long after the money left.

A return is not a failure — status stays "paid"

failed means the money never left and the reserved amount went back to your balance. A return means the opposite: the money did leave, reached the bank, and was handed back. So a returned payout keeps "status": "paid" and error_code: null, and reports the return in its own fields. Switch on returned, not on status.

FieldMeaning
returnedtrue once a settled payout has been sent back.
returned_atWhen the return arrived (ISO 8601).
return_codeThe return code, e.g. R03.
return_reasonThe bank's own words, e.g. NO ACCOUNT FOUND.

Subscribe to payout.returned to be told, or poll GET /payouts/:id. Your Paysio balance is credited back automatically once the returned funds reappear — it is your own recipient-side ledger that needs the signal.

JSON
{
  "data": {
    "id": "uuid",
    "object": "payout",
    "payout_number": 19,
    "payout_label": "#00019",
    "amount": 19600,
    "currency": "USD",
    "status": "paid",
    "rail": "ach",
    "error_code": null,
    "error_message": null,
    "returned": true,
    "returned_at": "2026-08-13T22:52:00.000Z",
    "return_code": "R03",
    "return_reason": "NO ACCOUNT FOUND",
    "created_at": "2026-08-12T02:58:37.000Z",
    "updated_at": "2026-08-13T22:52:00.000Z"
  }
}

Common errors

HTTPCause
400Insufficient available balance for the payout amount.
400Recipient has no usable billing ZIP / address for a card payout — set the customer's billing address first.
400Workspace is not on Paysio Debit & Payouts.
404Unknown customer_id or payment_method_id.
409Duplicate reference_id — a payout with this idempotency key already exists.
payout.failed M009 / M011Card cannot receive push-to-card funds (webhook-time failure — use POST /account-checks to catch this up front).