Fund your balance
Most payouts are paid from a USD balance you hold with Avvio. You top it up by wire or with USDC, and in the sandbox with one API call. Balance & funding explains what the balance is made of.
- Find where to wire with
GET /payments/organizations/{orgId}/payin-accounts. - In the sandbox, credit the balance with
POST .../sandbox/fundinstead. - Check what you can send with
GET /payments/organizations/{orgId}/balance. - For a payout that returns
requiresFunding: true, fund that one payout from your wallet.
-
Find where to wire
Section titled “Find where to wire”GET /payments/organizations/{orgId}/payin-accountsx-api-key: avvio_live_…{"accounts": [{"id": "sbx_acct_usd_cmsx0h2k900a1n11ib3qz9v42","currency": "USD","shape": "us","status": "active","paymentRails": ["wire", "ach"],"settlesTo": "provider_balance","destination": null,"balance": { "currency": "USD", "amount": 980000, "decimals": 2 },"depositInstructions": {"bank_name": "Example Bank","account_number": "****4471","routing_number": "123456789","beneficiary_name": "Avvio","reference": "ORG-7f3a91"}}]}Wire to
depositInstructions. Money you wire is held as your balance; it is not forwarded anywhere, and payouts debit it. When there is nothing to show, a live key gets{ "accounts": [] }; a test key also gets anotewith the reason. USD stablecoins in your organization’s wallet also count toward the balance.Wire lead time depends on your bank and the receiving bank, so confirm it with your Avvio contact and fund ahead of your first live run.
-
Fund the sandbox
Section titled “Fund the sandbox”There is no wire in the sandbox, and no
sandbox/fundin production:POST /payments/organizations/{orgId}/sandbox/fund IDEMPOTENCY_KEY=$(uuidgen) # new key per call; reuse it only to retry this exact requestcurl -s -X POST "$AVVIO_BASE_URL/payments/organizations/$AVVIO_ORG_ID/sandbox/fund" \-H "x-api-key: $AVVIO_API_KEY" \-H "Idempotency-Key: $IDEMPOTENCY_KEY" \-H "content-type: application/json" \-d '{"amount": "5000.00"}'POST /payments/organizations/{orgId}/sandbox/fund await avvio.fund('5000.00'); // test keys onlyPOST /payments/organizations/{orgId}/sandbox/fund import osimport uuidimport requestsidempotency_key = str(uuid.uuid4()) # new key per call; reuse it only to retry this exact requestres = requests.post(f"{os.environ['AVVIO_BASE_URL']}/payments/organizations/{os.environ['AVVIO_ORG_ID']}/sandbox/fund",headers={"x-api-key": os.environ["AVVIO_API_KEY"],"Idempotency-Key": idempotency_key,},json={"amount": "5000.00"},)print(res.status_code, res.json())POST /payments/organizations/{orgId}/sandbox/fund avvio-payments fund --amount 5000.00{ "balance": "10000.00" }amountdefaults to10000.00. Skip this once to see the400 INSUFFICIENT_BALANCEyour integration gets when the balance is short. -
Check the balance
Section titled “Check the balance”GET /payments/organizations/{orgId}/balancex-api-key: avvio_live_…{"currency": "USD","amount": "13185.03","balances": [{ "currency": "USD", "amount": "13185.03" }],"provider": [{ "currency": "USD", "amount": "10000.00" }],"wallet": [{ "currency": "USDC", "network": "Ethereum", "amount": "3185.030147" }],"unavailable": [],"ledger": [{ "currency": "USD", "available": "9800.00", "held": "200.00", "total": "10000.00" }]}Size payouts against
balances. Whenunavailableis non-empty the figures are a floor, so retry before deciding you cannot fund a payout. Reading the balance explains every field. -
Fund a payout that waits for you
Section titled “Fund a payout that waits for you”Some crypto and dedicated settlement routings price the transfer and wait for you to fund that one payout from your own wallet. You send the transfer from your registered wallet and report its transaction hash, unless your organization has opted in to automatic funding. A payout that needs funding says so in the creation response:
{"requiresFunding": true}Read the funding instructions
Section titled “Read the funding instructions”Call
GET /payments/organizations/{orgId}/payouts/{payoutId}/funding:GET /payments/organizations/{orgId}/payouts/sbx_pay_7c1c0f2e-6d9b-4a3e-9d1a-2f4b8c9e0a11/fundingx-api-key: avvio_live_…Response:
{"payoutId": "sbx_pay_7c1c0f2e-6d9b-4a3e-9d1a-2f4b8c9e0a11","amount": "200.00","currency": "USDC","depositAddress": "0x71C...492","network": "base","expiresAt": null}This is a pure read and starts no clock, so poll it freely.
amountalready includes the payout fee; nothing is added at funding time. See Fees.expiresAtis normallynull; it carries a time only when the network publishes one. Before sending against old instructions, check the payout’s status atGET /payments/organizations/{orgId}/orders/{payoutId}.Confirm the transfer
Section titled “Confirm the transfer”After you broadcast the transfer from your registered wallet, send its hash:
POST /payments/organizations/{orgId}/payouts/sbx_pay_7c1c0f2e-6d9b-4a3e-9d1a-2f4b8c9e0a11/funding/confirmx-api-key: avvio_live_…Idempotency-Key: 5a81e921-bc01-447a-9a11-0982716a5b42Content-Type: application/json{"transactionHash": "0x98a123...45f"}transactionHashis required. Confirmation also acceptsX-Allow-Duplicate: true(Idempotency).Before recording the deposit, Avvio checks the chain, on every network, Solana included. The transaction must:
- Exist on the designated network.
- Have successfully confirmed.
- Have transferred at least the required token amount to the exact
depositAddress. - Originate from the wallet registered for this payout, where the network exposes that check.
Confirmation errors
Section titled “Confirmation errors”Status Type Action 400FUNDING_TRANSACTION_ INVALID We read the transaction and it failed a check (reverted, wrong address, too little). Nothing is recorded and the payout stays open; send a correct transfer and confirm its hash 409FUNDING_NOT_ YET_ VERIFIABLE We could not verify it yet: not mined or not indexed. Your transfer is unaffected. Back off and confirm the same hash again Errors lists the rest.
Cancel a payout you will not fund
Section titled “Cancel a payout you will not fund”POST /payments/organizations/{orgId}/payouts/{payoutId}/cancel IDEMPOTENCY_KEY=$(uuidgen) # new key per call; reuse it only to retry this exact requestcurl -s -X POST "$AVVIO_BASE_URL/payments/organizations/$AVVIO_ORG_ID/payouts/$payoutId/cancel" \-H "x-api-key: $AVVIO_API_KEY" \-H "Idempotency-Key: $IDEMPOTENCY_KEY"POST /payments/organizations/{orgId}/payouts/{payoutId}/cancel await avvio.cancelPayout(payoutId); // only before it is fundedPOST /payments/organizations/{orgId}/payouts/{payoutId}/cancel import osimport uuidimport requestspayoutId = "<payoutId>"idempotency_key = str(uuid.uuid4()) # new key per call; reuse it only to retry this exact requestres = requests.post(f"{os.environ['AVVIO_BASE_URL']}/payments/organizations/{os.environ['AVVIO_ORG_ID']}/payouts/{payoutId}/cancel",headers={"x-api-key": os.environ["AVVIO_API_KEY"],"Idempotency-Key": idempotency_key,},)print(res.status_code, res.json())POST /payments/organizations/{orgId}/payouts/{payoutId}/cancel avvio-payments cancel <payoutId>You can cancel only a payout still waiting on your own funding (
requiresFunding). It reportscanceledand can no longer be funded. It was never debited, so your balance does not change and no ledger row is written. Once funded, cancel returnsPAYOUT_NOT_CANCELABLE; it cannot stop a payout in flight.Let us fund it for you (opt-in)
Section titled “Let us fund it for you (opt-in)”Ask us to enable automatic funding and we fund these payouts from your organization’s own wallet. Your API calls stay the same.
POST /payoutsthen sends the pay-in itself, a gas-covered USDC transfer from your wallet, verified as above. The response readsstatus: "processing", orpendingwithrequiresFunding: truewhile it confirms, usually within a minute or two; poll the order or take the webhook. If the wallet can’t cover it or the transfer can’t be sent, nothing is sent and the payout is left as a manually funded one,requiresFunding: truewith the instructions above still valid.
Was this page helpful?