Moves 1 and 4 are the only ones your customer takes part in, and both happen in the same HEVN popup on
your site: they sign in and allow access once, and they approve each payout you book. Everything else
is your backend alone. The window is described once, in
Sign in with HEVN, and never varies by product.
A marketplace with escrow
Your customer is a buyer paying a seller through your platform, and the money must not reach the seller until the goods do. Both parties are clients linked to you; you are the operator of the deal between them.1
Link both sides as clients
A deal binds two accounts linked to you through Sign in with HEVN. A buyer or seller you merely
referred to HEVN does not qualify —
POST /dapi/v1/escrow answers 422 receiver_not_a_client.2
Fund the buyer
Whatever gets a stablecoin balance onto the buyer’s wallet: a virtual account in the buyer’s own
name, or an on-chain transfer straight to
baseSmartWallet. Crypto in needs no rail and no
verification beyond a ready client.3
Open the deal and authorize it
POST /dapi/v1/escrow names senderClientId, receiverClientId and the three windows —
approveBy, holdUntil, refundableUntil — and the buyer approves it. Authorizing moves the money out of the buyer’s
wallet into the contract, where neither party, neither HEVN nor you can spend it outside the
contract’s rules.4
Capture when the seller delivers
POST /dapi/v1/escrow/{escrowId}/actions with action: "capture" and a feeBps — that is
your take rate, deducted from the captured amount before the seller is paid. Capture is
repeatable, so a partial delivery is a partial capture.5
Handle the unhappy paths
void returns the hold to the buyer; the buyer can reclaim it themselves after holdUntil has passed;
refund sends money back after a capture — and a refund leaves your own wallet, not the
seller’s, so keep a working balance in the deal’s token.availableActions on the deal rather than branching on status. The server computes it from
the amounts, the windows and what already landed on chain, so it is the only answer that accounts for
all three. Full matrix: Escrow actions.
Escrow is switched on per integrator. Ask for it before you build against it —
Going live.
A payables or payroll platform
Your customer is an employer. It holds one client account, collects into it, and pays many people in many countries out of it. Nothing here needs escrow, and the contractors are never clients.1
One client per employer
The employer links it through Sign in with HEVN; you verify it and open the virtual account for
the currency the employer funds in. From then on that one
cl_… is the whole relationship.2
Save each contractor as a contact
POST /dapi/v1/contacts carries the beneficiary’s account details in the same shape
GET /dapi/v1/banks returns them, plus a complete postal address. A contact is deduplicated by
its own details, so a retried create never forks one. Which identifiers a method needs is in
Rails and payment methods.3
Price the run before you commit to it
GET /dapi/v1/contacts/{contactId}/capabilities?amount=… reports every payable option for that
contact with its minAmount, maxAmount, feeBps and fixedFee, and anything that would
refuse the payout in blockers[]. Read it per contact and show your customer a total.4
Pay, one payout at a time
POST /dapi/v1/payouts with an Idempotency-Key derived from your own payroll-run id and the
contractor id — run-2026-09:contractor-441 — then a sign session the employer’s holder
approves in the window. That key is what makes the whole run safe to re-drive after a crash: a
repeat is the same payment, never a second one.5
Reconcile from the client's ledger
GET /dapi/v1/transactions on the employer client is the record your customer’s finance team
reads, and GET /dapi/v1/transactions/export renders it as a statement.amount when the employer’s budget is fixed, amountTo when the
contractor’s net is fixed — never both, and never re-derive the other side yourself. See
Conventions.
An embedded payments account
Your customer gets what looks like a bank account inside your product: payment details in their own company name, a balance, a statement and outgoing payments. HEVN is invisible.1
A client per customer, verified once
Your customer links their account in the sign-in window. The legal name in its verification
document becomes the name on the account details, so send the registered name with its suffix —
Northwind Trading Ltd, not Northwind.2
A named rail, not a pooled one
On a
named rail the partner bank opens the account in the client’s own legal name, so the
payer’s bank shows your customer and nothing about HEVN. On a pooled rail the account belongs
to the partner and a paymentReference is what attributes the money — fine when your product
generates the payment instruction, wrong when a human types it.3
Surface the balance from chain, not from your database
GET /dapi/v1/client/balance reads the client’s Base smart wallet directly, one row per
account. There is no HEVN ledger that holds an authoritative copy, and there should be
no copy of yours either.4
Let them pay out
Contacts plus payouts, exactly as above, each approved by your customer in the window. A wallet
contact on Base is paid straight from the balance with nothing converted; a bank contact goes
through a partner and is quoted.
What none of these do
They do not let you spend your customer’s money. A client account belongs to its holder, and every payment out of it is approved by the holder’s own key in the sign-in window — your developer key only books it. If what you want is to move money with no approval from anyone but your server, that is your own integrator account, signed by your key — see Signing.Next: Quickstart
Ten steps in the sandbox, from an empty account to money that moved on chain.