Skip to content
Payouts and disbursements

Reserve funds before the rail confirms. Settle exactly what was paid.

Payouts take time: bank files, payout providers and manual reviews. LedgerForge holds the funds while the outcome is pending, settles all or part of the hold, releases the remainder, and can require an independent approval above a threshold.

Inflight holdsPartial commitApprovalsSigned webhooks
PUT /transactions/inflight/:txID3000 units
  1. INFLIGHT30.00 reserved for a payout
  2. COMMIT24.00 settled when the provider confirms
  3. VOID6.00 remainder released
reserved = committed + released3000 = 2400 + 600
Illustration of an ordinary hold, using the commit request shape below.
The problem

Where this usually goes wrong

  • Money leaves before it is reserved

    Two payout jobs read the same balance and both decide there is enough. Without a durable reservation, the second one overdraws the account.

  • Partial outcomes go missing

    A provider pays part of a batch. If the ledger can only mark the whole payout as done or failed, finance reconciles the difference by hand.

  • One credential can send anything

    Large disbursements leave on a single API key. A second pair of eyes exists in a policy document, not in the system that moves the money.

API example

A 30.00 USD supplier payout above the approval threshold

Captured from a local LedgerForge build. The key's policy sets approval_above to 2000 units, so the server holds the 3000-unit payout and records a pending approval. A different key approves it and the held leg settles.
POST /transactionsRequest
{  "source": "bln_df56a248-7d7e-4c0c-8fbf-a5215c87b603",  "destination": "bln_173d086e-57cb-4690-9abe-1cf060fafb13",  "currency": "USD",  "precise_amount": 3000,  "precision": 100,  "reference": "payout-2207",  "description": "Supplier payout",  "skip_queue": true,  "allow_overdraft": true,  "overdraft_limit": 50}
Response (excerpt)201 Created
{  "precise_amount": 3000,  "precision": 100,  "transaction_id": "txn_1a536530-f07d-43a5-8f72-c89965d179cd",  "reference": "payout-2207",  "status": "INFLIGHT",  "inflight": true,  "meta_data": {    "policy_admission_id": "adm_dbebd5ed-78e0-40ce-a4a2-ab598a95e254",    "policy_approval": "pending"  }}
POST /approvals/:admission_id/approve200 OK
{  "admission_id": "adm_dbebd5ed-78e0-40ce-a4a2-ab598a95e254",  "api_key_id": "api_key_8224a822-7ec0-4e0e-8f8f-d95039fc8fb3",  "identity": "payout-2207",  "policy_version": 1,  "day": "2026-10-10T00:00:00Z",  "decision": "approved",  "decided_by": "api_key_02790ec7-4f42-462b-8044-a0df92c70086",  "legs": [    {      "transaction_id": "txn_1a536530-f07d-43a5-8f72-c89965d179cd",      "reference": "payout-2207",      "source": "bln_df56a248-7d7e-4c0c-8fbf-a5215c87b603",      "destination": "bln_173d086e-57cb-4690-9abe-1cf060fafb13",      "source_ledger": "ldg_e04e431f-8a27-4b19-8744-eb1867ed7b23",      "destination_ledger": "ldg_e04e431f-8a27-4b19-8744-eb1867ed7b23",      "currency": "USD",      "precision": 100,      "amount": "3000"    }  ]}
PUT /transactions/inflight/:txIDRequest shape
{  "status": "commit",  "precise_amount": 2400,  "skip_queue": true}

For an ordinary hold without a policy decision, settle with PUT /transactions/inflight/:txID. The body below commits 24.00 of a 30.00 hold; void releases what is left.

Put a provable ledger under your money movement

Start with the open-source core, or let the LedgerForge team run it for you on dedicated infrastructure.