Escrow locks USDC on-chain until release conditions are met: marketplace transactions, freelance milestones, or P2P trades. Create lock links for buyers, or lock directly via merchant API. Release, dispute, resolve, and claim-expired flows are all supported with prepare → sign → relay patterns. Trust issues, solved with smart contracts (the respectable kind).
Need machine-readable request/response bodies for your AI or codebase? Download this page as plain Markdown.
You create a lock link for a $2,000 design project. The client opens the hosted page, approves USDC, and locks funds. When the freelancer delivers, you POST /escrows/:id/release. If there's a dispute, either party escalates via dispute → resolve with a winner address. Drama optional. On-chain receipts mandatory.
Dashboard → Escrow
Create lock links, copy public URLs, monitor escrow status, release funds, raise disputes, and resolve conflicts, all with step-up PIN/2FA when enabled. Public buyer pages live at https://videpay.io/escrow/pay/{publicCode}.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
asset | string | Yes | Asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount to quote. |
/escrows/quote-feePreview gross, fee, and net amounts from the on-chain TokenRegistry Escrow fee bucket.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "2000"05}Verify buyer balance, allowance, and seller recipient status before locking.
| Field | Type | Required | Description |
|---|---|---|---|
buyerAddress | address | Yes | Wallet that locks USDC into escrow. |
sellerAddress | address | No | Vendor payout wallet. Defaults to merchant wallet. Must be an active transfer recipient when different. |
asset | string | Yes | Escrow asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount in human units. |
/escrows/readinessPre-flight check for a new lock: buyer USDC balance/allowance and seller recipient registry.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "2000",05 "buyerAddress": "0xBuyer123456789012345678901234567890123456",06 "sellerAddress": "0xSeller123456789012345678901234567890123456"07}/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/readiness?chain=baseReadiness for an existing escrow record (release, dispute, claim eligibility).
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
buyerAddress | address | Yes | Buyer wallet to check allowance for. |
asset | string | Yes | Escrow asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount. |
/escrows/buyer-approve/prepareReturn EIP-2612 permit typed data when buyer allowance is below lock amount.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "asset": "USDC",04 "amount": "2000",05 "buyerAddress": "0xBuyer123456789012345678901234567890123456"06}Lock funds directly without a public link. prepare-lock returns typed data; relay-lock submits the on-chain transaction via Videpay relayer.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
buyerAddress | address | Yes | Wallet that locks USDC into escrow. |
sellerAddress | address | No | Vendor payout wallet. Defaults to merchant wallet. Must be an active transfer recipient when different. |
asset | string | Yes | Escrow asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount in human units. |
releaseDelaySeconds | integer | Yes | Seconds before seller can claim expired funds (min 3600, max ~1000 days). |
reference | string | No | Your order or deal reference (max 100, unique per business). |
metadata | object | No | Arbitrary JSON stored on the escrow record. |
permitSignature | string | No | EIP-2612 permit signature when buyer allowance is insufficient. |
permitDeadline | string | No | Unix timestamp deadline from permit typed data. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/escrows/prepare-lockReturn readiness, optional permit typed data, and lock intent for wallet signing.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "buyerAddress": "0xBuyer123456789012345678901234567890123456",04 "sellerAddress": "0xSeller123456789012345678901234567890123456",05 "asset": "USDC",06 "amount": "2000",07 "reference": "order_12345",08 "releaseDelaySeconds": 60480009}/escrows/relay-lockExecute lock on-chain via relayer. Emits escrow.locked. Requires dashboard authorization when called from browser.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "buyerAddress": "0xBuyer123456789012345678901234567890123456",04 "sellerAddress": "0xSeller123456789012345678901234567890123456",05 "asset": "USDC",06 "amount": "2000",07 "reference": "order_12345",08 "releaseDelaySeconds": 604800,09 "metadata": {10 "orderId": "ord_12345"11 },12 "successRedirectUrl": "https://marketplace.example/orders/12345/done",13 "cancelRedirectUrl": "https://marketplace.example/orders/12345",14 "permitSignature": "0x...",15 "permitDeadline": "1751925600"16}/escrows/recover-lockRecover an escrow record from an existing on-chain lock transaction hash.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "txHash": "0xlocktx...",04 "reference": "order_12345"05}Shortcut that locks immediately when buyer allowance is already sufficient. Equivalent to relay-lock with requireExistingAllowance.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
buyerAddress | address | Yes | Wallet that locks USDC into escrow. |
sellerAddress | address | No | Vendor payout wallet. Defaults to merchant wallet. Must be an active transfer recipient when different. |
asset | string | Yes | Escrow asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount in human units. |
releaseDelaySeconds | integer | Yes | Seconds before seller can claim expired funds (min 3600, max ~1000 days). |
reference | string | No | Your order or deal reference (max 100, unique per business). |
metadata | object | No | Arbitrary JSON stored on the escrow record. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/escrowsCreate and lock escrow in one step when allowance exists. Emits escrow.locked.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "buyerAddress": "0xBuyer123456789012345678901234567890123456",04 "sellerAddress": "0xSeller123456789012345678901234567890123456",05 "asset": "USDC",06 "amount": "2000",07 "reference": "order_12345",08 "releaseDelaySeconds": 604800,09 "metadata": {10 "orderId": "ord_12345"11 },12 "successRedirectUrl": "https://marketplace.example/orders/12345/done",13 "cancelRedirectUrl": "https://marketplace.example/orders/12345"14}Lock links use esc-* public codes. Share lockUrl: buyers open the hosted page without your API key.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
buyerAddress | address | Yes | Wallet that locks USDC into escrow. |
sellerAddress | address | No | Vendor payout wallet. Defaults to merchant wallet. Must be an active transfer recipient when different. |
asset | string | Yes | Escrow asset symbol (USDC). |
amount | decimal string | Yes | Gross lock amount in human units. |
releaseDelaySeconds | integer | Yes | Seconds before seller can claim expired funds (min 3600, max ~1000 days). |
reference | string | No | Your order or deal reference (max 100, unique per business). |
metadata | object | No | Arbitrary JSON stored on the escrow record. |
successRedirectUrl | url | No | Browser redirect after buyer successfully locks funds. |
cancelRedirectUrl | url | No | Browser redirect when buyer abandons the lock flow. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
status | enum | No | Query filter: pending, locked, released, expired, cancelled. |
buyerAddress / reference | string | No | Query filters for list. |
/escrows/lock-linksCreate a hosted escrow lock link. Returns lockUrl for the buyer.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "buyerAddress": "0xBuyer123456789012345678901234567890123456",04 "sellerAddress": "0xSeller123456789012345678901234567890123456",05 "asset": "USDC",06 "amount": "2000",07 "reference": "order_12345",08 "releaseDelaySeconds": 604800,09 "metadata": {10 "orderId": "ord_12345"11 },12 "successRedirectUrl": "https://marketplace.example/orders/12345/done",13 "cancelRedirectUrl": "https://marketplace.example/orders/12345"14}/escrows/lock-links?status=pending&limit=20List lock links. Filter by status (pending, locked, released, expired, cancelled), buyerAddress, or reference.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/jsonBuyers interact with these endpoints from the hosted page at https://videpay.io/escrow/pay/{publicCode}. Use your public API key only if calling from your own frontend wrapper.
| Field | Type | Required | Description |
|---|---|---|---|
permitSignature / permitDeadline | string | No | Buyer EIP-2612 permit for relay lock. |
sessionId | uuid | No | Deposit session ID for status polling and realtime. |
/escrows/public/esc-k9m2x7Load lock link details, readiness, and available actions for the buyer.
01x-api-key: pk_AbCdEfGhIj_XyZ1234567890abcdefghij02Content-Type: application/json/escrows/public/esc-k9m2x7/relayBuyer relay lock: submit permit signature after USDC approval.
01Content-Type: application/json01{02 "permitSignature": "0x...",03 "permitDeadline": "1751925600"04}/escrows/public/esc-k9m2x7/deposit-sessionsCreate a deposit session for buyers who prefer sending USDC to a unique address instead of permit+relay.
01Content-Type: application/json01{02 "metadata": {03 "source": "hosted-page"04 }05}/escrows/public/esc-k9m2x7/status?sessionId=ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4bPoll deposit session or lock status from the hosted page.
/escrows/public/esc-k9m2x7/realtime-tokenIssue a short-lived WebSocket token for live status on the hosted page.
01Content-Type: application/json01{02 "sessionId": "ds_8e4f1a2b-3c5d-4e6f-7a8b-9c0d1e2f3a4b"03}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
status | enum | No | Query filter: locked, released, disputed, resolved, refunded. |
txHash | string | No | Optional sync anchor on GET or POST sync. |
/escrows?status=locked&limit=20List escrow records. Filter by status, buyerAddress, asset, or reference.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c?chain=baseRetrieve an escrow. Reconciles with on-chain state when stale or txHash provided.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/syncForce sync with on-chain state. Optionally pass txHash to anchor reconciliation.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "txHash": "0xlocktx..."04}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
actorAddress | address | Yes | Wallet that will sign the on-chain action. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/release/prepareReturn EIP-712 typed data for seller-signed release.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "actorAddress": "0xSeller123456789012345678901234567890123456"04}/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/releaseMerchant-initiated release via relayer. Emits escrow.released.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base"03}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
actorAddress | address | Yes | Wallet that will sign the on-chain action. |
winnerAddress | address | Yes | Address that receives funds on resolve: buyer or seller. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/dispute/prepareReturn typed data for dispute signature.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "actorAddress": "0xBuyer123456789012345678901234567890123456"04}/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/disputeRaise a dispute on-chain. Emits escrow.disputed.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base"03}/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/resolve/prepareReturn typed data for operator resolve with winnerAddress.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "actorAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",04 "winnerAddress": "0xSeller123456789012345678901234567890123456"05}escrow.claimable precedes claim-expired
When releaseDelaySeconds elapses, Videpay emits escrow.claimable. The seller then calls claim-expired to move funds on-chain.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
actorAddress | address | Yes | Wallet that will sign the on-chain action. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/claim-expired/prepareReturn typed data for seller claim-expired.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base",03 "actorAddress": "0xSeller123456789012345678901234567890123456"04}/escrows/esc_7f3a9b2c-4d1e-4a8f-9c0b-1e2d3f4a5b6c/claim-expiredSeller claims funds after release delay expires.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "chain": "base"03}| Field | Type | Required | Description |
|---|---|---|---|
id / escrowId | uuid / bytes32 | No | Videpay record ID and on-chain escrow hash. |
status | enum | No | locked, released, disputed, resolved, refunded. |
parties | object | No | operatorAddress, buyerAddress, sellerAddress, recipientAddress. |
amounts | object | No | grossAmount, feeAmount, netAmount (raw + formatted). |
releaseDelaySeconds / releaseAfter | integer / datetime | No | Lock duration and earliest claim-expired time. |
transaction.*TxHash | string | No | On-chain hashes for create, release, dispute, resolve. |
Register a webhook endpoint and verify the X-Protocol-Signature header on every delivery before fulfilling orders or updating your database.
escrow.lockedSent when buyer funds are locked on-chain.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.locked04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...escrow.claimableSent when release delay expires and the seller can claim expired funds.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.claimable04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...escrow.disputedSent when either party raises a dispute on-chain.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.disputed04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...escrow.releasedSent when the seller releases funds to the recipient.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.released04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...escrow.resolvedSent when a disputed escrow is resolved with a winner.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.resolved04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...escrow.refundedSent when locked funds are refunded to the buyer.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: escrow.refunded04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...