Skip to main content
Spendin holds no balance for you. There is no wallet, no ledger, and no withdrawal endpoint. When a payout fails after your settlement has already arrived, the money is sent straight back out to a destination you registered in advance. That is why registering the destination is a precondition of creating a payout rather than a step at refund time. A failed payout can always be returned because we insisted on knowing where to before we let you start.

Register a destination

One destination per settlement currency. Setting one again replaces it.
network must be TRON or BSC. No other chain is accepted.
Crypto addresses cannot be verified — chains have no account names, so is_verified stays false and you own the correctness of the address. A refund sent to a mistyped address is gone. Check it character by character, and confirm the network matches the address format.
Requires the refunds:manage scope.

What you registered

Account numbers and addresses are always masked. PII never leaves whole, not even back to you — you already hold the values you registered.

When a refund happens

Exactly one condition: the payout reached FAILED and a matched settlement exists. A payout that failed before your money arrived has nothing to return. A refund is raised within about a minute of the payout failing. The payout itself gets is_refunded: true and a refund_reference at the same moment.
EXPIRED payouts never produce a refund. Expiry means the instruction lapsed with no money received, so there is nothing to send back.

What you get back

What actually arrived, minus the cost of sending it back out.
The deduction is the network or transfer fee for the rail — a TRC-20 or BEP-20 network fee for crypto, a bank transfer fee for NGN. If that fee is unconfigured it resolves to zero rather than a guess, so a misconfiguration on our side can never quietly shortchange you. Note that received_amount is what arrived, not what was expected. Overpay a payout that later fails and the excess comes back too.

Reading refunds

Every refund names the payout_id and inflow_id it returns, so you can always trace money back to the failed payment that produced it. All three need refunds:read.

Replacing a destination mid-flight

A refund snapshots the destination when it is created. Change your destination afterwards and an in-flight refund still goes where it was already sent — the history is not rewritten. The snapshot fields on the refund (destination_masked, destination_bank_code, destination_network) are the record of where the money actually went, not where your current destination points.

Two failure modes worth handling

If a payout fails and no destination exists for its settlement currency, no refund is created. The money is held and escalated to our operations team rather than sent somewhere unverified.Nothing is lost, but resolution needs a human. Keep a destination registered for as long as you have payouts in flight.
A refund that exhausts its retries stops at FAILED. This is your money sitting undelivered, so it is an operational escalation on our side, not a resting state — but you should alert on it too.The usual causes are an address on the wrong chain or a bank account that has since been closed. Both need a corrected destination before we can retry.

Webhooks

Subscribe to these rather than polling:
All four refund.* events carry a payout snapshot in data, with "object": "payout" — not a refund object. Use event_type to tell them apart and data.id as the payout ID, then call GET /v1/payouts/{id}/refunds for the refund amounts. See Webhook events.