Skip to main content
A payout transfers funds from one of your wallets to one payee’s bank account, in the payee’s currency. You create payouts with POST /payouts: a single call creates between 1 and 100 payouts, groups them in a batch, prices them, reserves their total in the wallet you choose, and sends every payout whose payee is ready.

How it works

  1. Validate. Infinity checks every item: the payee exists and can be paid in that currency, the amount meets the currency’s rules, and each payee appears once.
  2. Price. Each payout is priced at the current rate with your account’s fee_bearer, exactly as a quote would price it.
  3. Reserve. The total debit_amount is checked against the wallet’s available amount and reserved.
  4. Send or hold. Payouts to active payees are handed to the payout network as pending. Payouts to payees who aren’t ready yet are created awaiting_payee and wait, with their funds reserved, until the payee is ready.
The call is atomic. If any item fails validation, or the total doesn’t fit in the wallet, the request fails and no batch, payout or reservation is created, so you never have to reconcile a partially created set.

Create payouts

Response (abridged)
Maria is active, so her payout was sent immediately. Northwind Studio hasn’t finished onboarding, so its payout is on hold until it does, and the batch reports awaiting_payees. The response is the batch, with every payout it created in payouts, in request order.

Request

Each item: The Idempotency-Key header is required. A retry with the same key and body returns the original batch instead of creating a second one; see Idempotency. When a request fails validation, param points at the offending field, for example items[1].amount. Pricing and balance failures that concern the request as a whole return param: null.

What you’re charged

Each payout records what it cost: Quotes and pricing explains how fee_bearer changes these amounts.

Payout statuses

failed, canceled and expired are terminal. paid is final except for one transition: a bank can return a payout days after crediting it, which moves it to returned. Don’t treat a payout as irrevocably settled in your ledger until you’re comfortable with that window.

Payouts on hold

You can pay a payee before they’ve finished onboarding. The payout is created as awaiting_payee and its full debit_amount is reserved in the wallet, so the funds can’t be spent twice.
  • Release. Infinity releases payouts on hold once a day at 09:00 IST. A payout is released if its payee is active and has been for at least 5 minutes. Released payouts are priced again at the current rate; any difference from the reserved amount is taken from, or returned to, the wallet.
  • Insufficient funds at release. If the wallet’s available amount can’t cover the repriced payout, it moves to awaiting_funds and is retried at every daily release until it’s sent or expires. Funding the wallet doesn’t release it by itself.
  • Expiry. hold_expires_at is set at creation from your account’s hold_expiry_days. A payout still on hold at that time moves to expired and its reservation is released.
  • Currency. A payee’s first payout on hold fixes their currency. Later payouts to that payee must use the same currency.

Update a payout on hold

You can change amount, and currency while the payee has no bank account and no other payouts on hold. The payout is priced again and its reservation replaced; an increase is checked against the wallet’s available amount. description, reference and metadata can’t be changed. Infinity emits payout.updated.

Cancel a payout on hold

The payout moves to canceled and its reservation is released. Both update and cancel are allowed only in awaiting_payee and awaiting_funds; in any other status they fail with 409 payout_not_editable.

Failure codes

When a payout is failed or returned, failure_code identifies the cause and failure_message carries a fixed description of it. New failure codes may be added. Treat an unknown code as a generic failure and route it for review.

Retrieve and list payouts

GET /payouts filters by status, payee_id, batch_id, created[gte] and created[lte], returns results newest first and pages with limit (up to 100) and starting_after. GET /payouts/{id} returns one payout as it is now.

Events

Each payout emits payout.created when it’s created, then one event per status change: payout.pending, payout.awaiting_funds, payout.processing, payout.paid, payout.failed, payout.returned, payout.canceled and payout.expired. An update emits payout.updated. Every event carries the full payout object as it was at that moment. See Webhooks.