Holds

A hold sets money aside in an account without moving it yet. The reserved amount shifts into the account's held balance and lowers what is available to spend, but no money changes hands until you decide what happens next. You either capture the hold, which settles it to a destination account, or release it, which frees the funds.

This is the same two-step model card networks use. An authorization reserves the funds at the moment of purchase, and a later capture actually charges them, often for a different amount once the final total is known. Holds let you build that pattern, and others like escrow or a pending withdrawal, on the ledger.

All hold endpoints require the program_id header.

The hold object

Field Type Description
hold_id string Unique identifier.
entity_id string The account whose funds are reserved.
amount integer The total reserved, in minor units.
captured_amount integer How much has been captured so far.
status string held, partially_captured, captured, released, or expired.
expires_at string An optional time after which the hold releases on its own.

How a hold plays out

Placing a hold requires enough available balance to cover it, or it is rejected with 422 insufficient_funds. When you capture, you settle some or all of the reserved amount to a destination account. A capture can be partial: taking less than the full amount leaves the hold partially_captured with the remainder still reserved, ready for another capture or a release. Releasing cancels whatever is still reserved and returns it to the account's available balance.

Operations

Method and path What it does
POST /hold Reserve funds in an account.
POST /hold/capture Settle some or all of a hold to a destination account.
POST /hold/release Cancel whatever remains reserved.
GET /hold Retrieve one hold.
GET /holds List holds in the program.
POST /holds/expire Release any holds that have passed their expires_at.

The API reference documents the parameters and responses for each of these.