Only move 4 needs a signature, and it is always the same one: HEVN builds the operation, you check
the
debit it echoes and sign it, HEVN co-signs and submits. That mechanism is described once, in
Signing, 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 you created; you are the operator of the deal between them.1
Create both sides as clients
A deal binds two accounts you provisioned yourself. 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. 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; reclaim does the same 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
Create it, 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 sign and confirm. 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
The legal name you send at creation 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. 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 your customer sign. A client account has no login and no signer of its own: every movement starts with your developer key and is co-signed by HEVN, which is the whole shape of the whitelabel model. If what you want is an account whose owner signs for themselves, that is the self-serve product — see What is HEVN.Next: Quickstart
Nine steps in the sandbox, from an empty account to money that moved on chain.