Skip to main content
Escrow holds a buyer’s funds in trust until both parties confirm that the agreed work has been delivered. Neither party can access the money unilaterally — Vouch releases it only after mutual confirmation. This makes escrow ideal for any marketplace or platform where payment and delivery happen at different times: freelance projects, service agreements, goods purchases, and more. Consider a concrete example throughout this guide: a client (buyer) hires a freelancer (seller) to build a website. The project is split into two milestones — a design phase and a development phase — each with its own payment. The client funds the escrow upfront; the freelancer gets paid only after both parties confirm each milestone.
1

Create the Agreement

Call vouch.escrow.create() with the buyer and seller’s IDs from your platform, the total contract value, and the milestone breakdown. Vouch returns an AgreementResponse containing the agreement ID you’ll use for all subsequent calls.
Both the buyer and seller are referenced by the IDs you already use on your platform. Vouch does not require you to create separate Vouch user accounts.
2

Pre-Funding Fraud Check

Before showing the buyer payment details, run a fraud assessment against the agreement. If the flag is GREEN, Vouch returns a virtual bank account the buyer can transfer funds to. If it is RED, block the funding flow entirely.
The virtual account is unique to this agreement. Direct the buyer to transfer the exact totalAmount to that account number. Vouch detects the incoming transfer and updates the agreement status automatically.
3

Buyer Sends Funds

Once you display the virtual bank account details, the buyer completes the transfer through their bank or payment app — no further SDK call is needed on your part to initiate this step. Vouch monitors the virtual account and updates the agreement status as funds arrive.You can notify the seller when the status reaches FUNDED so they know work can begin.
4

Track Agreement Status

Poll vouch.escrow.status() to check on an agreement at any point. Use this to update your UI, trigger notifications, or confirm that funds have arrived before allowing the seller to start work.
For time-sensitive flows, poll every 30–60 seconds after the buyer initiates the transfer, or use a webhook if your Vouch plan supports it.
5

Confirm a Milestone

When the seller delivers a milestone, both the seller and the buyer must call vouch.escrow.confirm() with the agreement ID and the milestone ID. Disbursement triggers automatically once both confirmations are received.
Funds are only released after both parties confirm the same milestone. Confirming as only one party puts the milestone in a pending-confirmation state — the agreement stays in IN_PROGRESS until the second confirmation arrives.
Repeat this step for each milestone. The agreement moves to COMPLETED once all milestones are confirmed.
6

Disbursement

After the final milestone receives mutual confirmation, Vouch automatically disburses the corresponding milestone amount to the seller’s account. The agreement status moves through COMPLETEDDISBURSED.
No manual disbursement call is required. Vouch handles the payout as soon as the confirmation threshold is met.

Error Scenarios

OVERFUNDED — If the buyer transfers more than totalAmount, Vouch records the surplus and the agreement continues normally. The excess is tracked separately and can be refunded or applied to a follow-on agreement. Your UI should inform the buyer of the overpayment without blocking the workflow.
FROZEN — If Vouch’s fraud detection flags the agreement with a RED signal at any point during its lifecycle, the agreement is frozen and no funds move. Contact Vouch support with the agreementId to initiate a review. Do not attempt to re-create the agreement until the freeze is lifted.
REFUNDED — If the agreement is cancelled before any milestone is confirmed (e.g. by mutual consent or dispute resolution), Vouch returns the held funds to the buyer and sets the status to REFUNDED.

Complete End-to-End Example

The following shows the full lifecycle in a single async function.