Payouts
A payout sends funds from one of your vaults to an external address. You pick the vault, the asset, the network, and the destination — Stridge funds the gas, signs from the non-custodial vault wallet, broadcasts, and tracks the transaction to a terminal state.
Every payout is a durable record you can fetch forever via GET /v1/transfer/payout/{id}, and every state change fires a webhook.
Vaults are available in select regions only and to select clients
only. Availability depends on the regulation that applies to your tenant
and on eligibility — vaults are not enabled for every account. If
GET /v1/vault returns an empty list, your tenant isn't vault-enabled yet.
Stridge holds vault keys in a non-custodial, third-party key-management
system — Turnkey or dfns —
and never holds raw private keys. See Vaults for the
full custody model.
Stridge does not hold, custody, or safeguard funds on behalf of end users.
- Treasury accounts are provisioned for and operated by merchants for business settlement and payout purposes.
- Stridge may facilitate transaction signing and execution through integrated key-management infrastructure solely to process merchant-authorized payout instructions.
- Merchants remain solely responsible for the underlying funds, recipient selection, transaction authorization policies, and compliance with applicable laws and regulations.
- Stridge acts as a technology and orchestration provider and does not provide banking, custodial, escrow, fiduciary, or money-transmission services.
Why payouts
Disbursing crypto yourself means running hot wallets, holding native gas on every chain, signing transactions safely, and reconciling on-chain state against your ledger. Payouts collapse that into one authenticated call:
- No key custody. Vault keys live in Turnkey or dfns; Stridge orchestrates signing without ever exporting a private key.
- No gas management. Every payout needs native gas on its network. If the vault wallet is short, Stridge auto-refills it from a gas station before executing — you never pre-fund gas.
- Idempotent by design. A
reference_idyou own deduplicates retries, so a dropped connection never double-pays. - Fully tracked. Each payout has a lifecycle and a webhook for every terminal state, so your ledger stays in sync without polling.
How a payout works
List your vaults with GET /v1/vault and choose the one that holds the asset you want to send. Each vault has an id and a human label (for example hot).
Call POST /v1/transfer/payout with the vault_id, asset, network_symbol, to_address, and your own reference_id. Specify the amount in crypto (amount) or in dollars (usd_amount) — Stridge converts at the current rate and records it.
Stridge checks that the vault wallet holds enough native gas for the transfer. If it doesn't, a gas-station refill runs automatically first — the payout waits in queued until gas is in place. You do nothing.
Stridge requests a signature from the vault's key-management provider, broadcasts the transaction, and moves the payout to processing.
When the transaction confirms you receive payout.confirmed with the on-chain tx_id. If it can't be delivered you receive payout.failed with an error. The payout record carries the same final state.
Creating a payout
The minimum request identifies the vault, the asset and network to send on, the destination, your reference, and an amount.
{
"vault_id": "550e8400-e29b-41d4-a716-446655440001",
"asset": "USDT",
"network_symbol": "ethereum",
"to_address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"reference_id": "order-12345",
"amount": "100.50",
"remark": "Payment for order #12345",
"type": "normal",
"expired_at": "2026-01-01T01:00:00Z"
}| Field | Required | Notes |
|---|---|---|
vault_id | yes | The vault the funds leave from |
asset | yes | Asset symbol to send, e.g. USDT |
network_symbol | yes | Network slug, e.g. ethereum, tron |
to_address | yes | External destination address |
reference_id | yes | Your idempotency key — unique per vault |
amount | one of | Crypto amount to send |
usd_amount | one of | USD amount; converted to crypto at the current rate |
remark | no | Free-form note stored on the payout |
type | no | normal (default) or forceful — see Payout type |
expired_at | no | Cutoff after which a non-confirmed payout expires. Defaults to 1 hour from creation; capped at 12 hours ahead. Ignored for forceful payouts. |
Provide either amount or usd_amount, not both. With
usd_amount, Stridge converts at submit time and records the rate and
resulting crypto amount on the payout so you can reconcile exactly what
was sent.
Payouts are idempotent by (vault_id, reference_id): re-submitting the same reference_id returns 409 Conflict instead of sending twice. Use an id you already own — an order id, an invoice id, a ledger row id.
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"vault_id": "550e8400-e29b-41d4-a716-446655440001",
"asset": "USDT",
"network_symbol": "ethereum",
"amount": "100.50",
"usd_amount": "100.50",
"rate": "1.0001",
"to_address": "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B",
"reference_id": "order-12345",
"remark": "Payment for order #12345",
"type": "normal",
"status": "confirmed",
"tx_id": "0xabc123def456789",
"error": "",
"created_at": "2026-01-01T00:00:00Z",
"confirmed_at": "2026-01-01T00:05:00Z",
"expired_at": "2026-01-01T01:00:00Z"
},
"message": "operation completed successfully",
"success": true
}Full request and response schemas live in the API reference.
Payout type
Every payout carries a type that controls how Stridge handles a vault that can't immediately cover the transfer.
| Behavior | normal (default) | forceful |
|---|---|---|
| Gas refill when the vault is short | Refills from a gas station, then sends | Refills, then sends |
| Retries | Until expired_at | Single attempt — refill and transfer each tried once |
expired_at | Honored (1h default, 12h cap) | Ignored |
Both types refill gas when the vault is short and then send the payout — type only changes retry behavior. normal keeps retrying the refill and the transfer until the payout confirms or reaches expired_at. forceful is single-attempt: the refill and the transfer are each tried once, and if either can't complete the payout fails immediately (it carries no expired_at). Use forceful when an immediate failure is preferable to Stridge retrying.
Lifecycle
status | Meaning |
|---|---|
queued | Accepted and waiting — gas is being refilled if the vault was short. Still retryable by Stridge. |
processing | Signed and broadcast; awaiting on-chain confirmation. |
confirmed | Transaction landed. tx_id and confirmed_at are populated. |
failed | Broadcast could not complete; error carries the reason. |
expired | Reached expired_at without confirming, or was rejected while pending. |
Rejecting a pending payout
A payout still in the queue can be cancelled with POST /v1/transfer/payout/{id}/reject. Stridge stops retrying it and it transitions to expired through the normal flow — a payout.expired webhook fires when it does.
curl -X POST 'https://api.stridge.com/v1/transfer/payout/{id}/reject' \
-H 'X-API-Key: '"$STRIDGE_API_KEY"''Rejecting is only valid while the payout is pending. A payout that has already reached a terminal state (or moved past pending) returns 409 Conflict.
Webhooks
Three events cover the terminal states of a payout:
| Event | Fires when |
|---|---|
payout.confirmed | The transaction landed on-chain |
payout.failed | Broadcast could not complete |
payout.expired | The payout expired or was rejected while pending |
All payout webhooks use the standard signed envelope. Full payloads are in Payout webhook events.
API surface
| Endpoint | Purpose |
|---|---|
GET /v1/vault | List vault accounts for the tenant |
GET /v1/vault/{vault_id}/addresses | Vault addresses across networks |
GET /v1/vault/{vault_id}/addresses/{network} | Vault address on one network |
GET /v1/vault/{vault_id}/balances | Balances per asset, with optional filters |
GET /v1/vault/{vault_id}/total | Total USD value across the vault |
POST /v1/transfer/payout | Create a payout from a vault |
GET /v1/transfer/payout | List payouts for a vault |
GET /v1/transfer/payout/pending | List queued (pending) payouts |
GET /v1/transfer/payout/{id} | Fetch one payout |
POST /v1/transfer/payout/{id}/reject | Cancel a pending payout |
GET /v1/gas-stations/wallets | List gas-station wallets |
GET /v1/gas-stations/address/{address} | Gas station details + balances by address |
GET /v1/gas-stations/wallet/{wallet_id} | Gas station details + balances by wallet id |
See the API reference for full schemas and error codes.
Next
- Payout Quickstart — send your first payout end-to-end in a few minutes.
- Vaults — the non-custodial vault model, addresses, balances, and regions.
- Gas station — how native gas is auto-refilled for every payout.
- Payout webhook events — payloads for
payout.confirmed,payout.failed,payout.expired.