Skip to main content

Pending Transfers

POST /v1/transfers

A pending transfer reserves funds without finalizing them. The amount is held on the debit account but not yet credited to the receiver. You then post (confirm) or void (cancel) it.

How it works

Step 1: Reserve. Create a pending transfer. The debit account's debits_pending increases. The credit account's credits_pending increases. Neither account's posted balances change. The funds are locked.

Step 2: Resolve. Do one of three things:

Post it. The reserved amount moves from pending to posted. The debit account's debits_posted increases, the credit account's credits_posted increases. The money has moved.

Void it. The reserved amount is released. Both accounts return to their state before the pending transfer. The money never moved.

Let it expire. If you set a timeout and the transfer is not posted or voided in time, it auto-voids. The funds are released automatically.

When to use

Authorization holds. A ride-hailing app holds the estimated fare when the ride starts, then posts the actual fare when it ends.

Escrow. Hold buyer funds until the seller delivers, then post. If the deal falls through, void.

Approval workflows. Reserve funds when a request is submitted. Post after manager approval. Void if rejected.

Request

{
"debit_account_id": "ba9755d7e835cdeea6bca803721c7eba",
"credit_account_id": "19d64e32e2da3c3dbd1ebaba9860ab9",
"amount": 50000,
"ledger": 1001,
"code": 100,
"pending": true,
"timeout": 3600
}
FieldRequiredDescription
pendingYesSet to true
timeoutNoSeconds until auto-void. Omit for no expiry.

The timeout is an interval in seconds, not an absolute timestamp. If you set timeout: 3600, the transfer expires 1 hour after creation.

Response 201

{
"data": {
"tenant_id": "f714f6af-...",
"transfer": {
"id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"debit_account_id": "ba9755d7e835cdeea6bca803721c7eba",
"credit_account_id": "19d64e32e2da3c3dbd1ebaba9860ab9",
"amount": 50000,
"ledger": 1001,
"code": 100,
"status": "pending",
"timeout": 3600,
"created_at": "2026-04-06T22:50:00Z"
}
}
}

Balance validation is immediate

Pending transfers validate the balance at creation time, not at post time. If the debit account does not have enough funds when you create the pending transfer, it fails immediately. It does not wait until you post it to check.

This means posting and voiding will never fail due to balance constraints. The funds were already validated and reserved.

Partial posting

When you post a pending transfer, you can post a smaller amount than was originally held. The remainder is released back to the debit account.

A ride costs an estimated 15,000. You hold 15,000. The actual fare is 12,000. You post 12,000. The remaining 3,000 is released.

A pending transfer can only be resolved once

You cannot post a transfer twice, void it after posting, or post it after voiding. Each pending transfer has exactly one resolution.

AttemptResult
Post then post againalready_posted error
Void then void againalready_voided error
Post then voidalready_posted error
Void then postalready_voided error
Expired then postexpired error

Headers

Authorization: Bearer qk_live_...
Idempotency-Key: <unique-string>
Content-Type: application/json