Payouts

Pay out to a bank account

Changed on

Natively cross-currency. Pass a quoteId and the FX runs as an LP_EXECUTION leg inside this one PAY_OUT, alongside the FIAT_RAIL leg.

The balance to debit is inferred from the customer and the quote's pair. You never pass it. The linked account has to be VERIFIED, and its currency has to equal the quote's toCurrency.

How the rail is resolved. In order: the quote's rail if you passed a quote, then the body's rail, then the destination's rail if it only supports one. Whatever resolves has to be in the destination's supportedRails[], or you get rail_mismatch. A SPEI quote can't fund a PIX account. If the destination supports several rails and neither the quote nor the body names one, the request fails with validation_error on rail. The resolved combination of country, currency and rail has to be a LIVE route, or it's route_unsupported.

When you need a quote. Only for a genuine FX pair, which means the funding balance and the destination are different fiat currencies, or the funding balance is a stablecoin and the destination isn't USD.

A same-currency payout is a plain transfer with no FX leg and no quote. USD Corporate Account out to USD over ACH or wire is one. So is an MXNa local balance out to MXN over SPEI.

USDC or USDT going to USD is a par redemption priced from the fee table. A quote is optional there, to lock fees, and never required. No artificial conversion is ever introduced.

Wait on payout.fiat.updated. See Webhooks and events.

post/v1/customers/{customerId}/payouts/fiat

Request

  • Base URL
    https://api.sandbox.alfredpay.io
  • URL
    https://api.sandbox.alfredpay.io/v1/customers/{customerId}/payouts/fiat
  • Auth
    • HTTP bearer
    • or API key in header api-key and API key in header api-secret

Headers

Idempotency-Keystring uuid required

Required on every state-changing POST, simulators included; the only exempt POST is …/verifications/preflight. Replay (same key, same body) returns the original response with Idempotent-Replayed: true; same key with a different body → 409 idempotency_conflict. Keys are UUIDs, scoped to the API key, retained for 24 hours.

Request body

linkedAccountIdstring required
quoteIdstring

Required only for a genuine FX pair (different fiat currencies, or stablecoin → non-USD fiat). Omit for a same-currency payout; optional for a USDC/USDT → USD par redemption.

rail'ACH' | 'WIRE' | 'SPEI' | 'PIX' | 'COELSA' | 'FPS' | 'CHATS'

The Rail values a fiat quote may carry, so every rail except WALLET.

referencestring
payment_flow_idstring
metadataMetadata

Client-supplied key–value pairs, echoed on the object and every event about it.

Example request

{
  "amount": {
    "value": "10000.00"
  }
}

Response

Created

transaction_idstring required
transaction_type'PAY_IN' | 'PAY_OUT' | 'CONVERSION' required
pay_in_subtype'COLLECTION' | 'ON_RAMP' | 'USD_STABLE_DEPOSIT' | 'null' nullable
pay_out_subtype'OFF_RAMP' | 'FIAT_WITHDRAWAL' | 'CRYPTO_WITHDRAWAL' | 'CROSS_BORDER_PAYOUT' | 'null' nullable
conversion_subtype'OTC_TRADE' | 'BALANCE_CONVERSION' | 'null' nullable
transaction_status'CREATED' | 'PENDING_VALIDATION' | 'PENDING_FUNDS' | 'PENDING_COMPLIANCE' | 'PENDING_RFI' | 'APPROVED_FOR_EXECUTION' | 'PROCESSING' | 'COMPLETE' | 'FAILED' | 'CANCELLED' | 'BLOCKED' required

Business lifecycle, customer-facing. Terminal values are COMPLETE, FAILED, CANCELLED, BLOCKED.

compliance_status'NOT_REQUIRED' | 'PENDING_SCREENING' | 'PENDING_KYT' | 'CLEARED' | 'ALERTED' | 'RFI_REQUESTED' | 'PAUSED' | 'ESCALATED' | 'RELEASED' | 'BLOCKED' required
settlement_status'NOT_STARTED' | 'FUNDS_EXPECTED' | 'FUNDS_RECEIVED' | 'FUNDS_HELD' | 'FUNDS_RELEASED' | 'SETTLED' | 'PARTIALLY_SETTLED' | 'FAILED' | 'RETURNED' required

Leg-level and financial. "Delayed settlement" is a settlement value with the parent still PROCESSING, never a business status.

reconciliation_summary'ALL_MATCHED' | 'PARTIAL_MATCH' | 'HAS_BREAK' required

Derived, visibility only. Never blocks transaction_status.

payment_flow_idstring nullable

Relates independent transactions in one flow. One completing never completes another.

resource_versioninteger

Monotonic per resource. Apply events in this order.

created_atstring date-time
updated_atstring date-time
idstring
customerIdstring
linkedAccountIdstring
quoteIdstring nullable
rail'ACH' | 'WIRE' | 'SPEI' | 'PIX' | 'COELSA' | 'FPS' | 'CHATS' | 'WALLET'

The scheme family a payment moves on. Never a country, provider or account identifier. ACH is any domestic batch bank transfer (US ACH, and the local clearing houses of COL, CHL, PER, BOL, PRY, DOM, CHN); WIRE is RTGS/SWIFT/Fedwire; SPEI, PIX, COELSA, FPS and CHATS are named instant schemes with their own semantics (COELSA is Argentina's instant transfer, deliberately not folded into ACH); WALLET is a stablecoin destination. Cash pickup is not in this release and has no rail value yet. Which rails a destination supports is derived by Alfred and returned as supportedRails[]; which (country, currency, rail) combinations are live is published by GET /v1/countries/{country}.

Example response

{
  "amount": {
    "value": "10000.00"
  }
}

Changes