Why reserve money first
Some spending happens in two steps. A purchase order is placed today and invoiced next week. A delivery is booked now and the final price is known later. If you only record the expense at the end, another payment could use the same money in between, and the second one would fail.
A hold solves this. It moves money from available to held straight away. The balance does not change, but nothing else can spend the held amount.
The three ways a hold ends
A hold can be captured once only, and never after it expires. Capturing the same hold twice returns the first result instead of charging again.
| Action | What happens |
|---|---|
| Capture | Records the expense for the real cost, up to the held amount. Any difference goes back to available. |
| Void | Cancels the hold. All of the money goes back to available. |
| Expire | Unused holds expire after 7 days (or the time you chose, up to 30 days). Their money comes back the next time money leaves the account, or when you release them. |
Holds from your software
Holds are for server keys with the holds:write permission. Each key can also have a cap on how much it may hold in total, so a bug cannot lock up a whole account.
1// When the order is placed
2const { hold } = await finance.holds.authorize({
3 accountId: "acc_3f9a1c",
4 amount: 500,
5 description: "Stock order PO-1042",
6 expiresInMinutes: 60 * 24 * 3, // three days
7});
8
9// When the invoice arrives
10await finance.holds.capture(hold.id, { amount: 480 });
11
12// Or, if the order is cancelled
13await finance.holds.void(hold.id);Holds in the dashboard
On the Accounts page, each account shows its held money. Open an account to see its open holds, capture one with the amount actually paid, or release it. Owners can release every hold on an account at once.
Approved spend requests also create holds, which is how an approval stays guaranteed until the money is spent. See Approvals and spend requests.
Holds follow the same rules as spending
