Skip to main content
In about twenty minutes you will have a client account linked to yours through the HEVN sign-in window, holding testnet USDC, with one payout its holder approved and HEVN settled on chain. Ten steps, all of them in the sandbox.

Before you start

  • Create a sandbox account in a browser. Sign up at https://sandbox.gethevn.com with your work email. Sandbox and production are separate accounts; nothing you do here touches real money.
  • Create a developer key, in the same browser. Open Settings → Partner program → Developer and create one. You set one thing that can never be changed afterwards: the IP allowlist, which for this quickstart is the egress address of the machine you will run it from. Every later call is re-checked against it — a request from an address you did not list is a 403 however correct the key and the signature are.
  • Allow your local site in the sign-in window. On the same tab, in the Sign-in window card, add http://localhost:8080 under Allowed sites and save. Give the window a title while you are there; it is what your test customer will see.
  • Have a second Google account ready. It plays your customer. It must not have a HEVN sandbox account of its own: an existing account answers already_registered and can never be linked.
  • Save the private key into your environment. The browser shows it once. Write it to $HEVN_KEY_PEM with mode 0600; HEVN never holds it and cannot show it again. Walk-through: Developer key.
  • Set the environment and install two dependencies. Everything after that is code.
Every example on these pages reads the same variables:
Three more come out of the first two: HEVN_ACCESS_TOKEN, the one-hour token logging in returns; HEVN_USER_ID, your own account’s cl_… id, which the same response returns as userId and which the /client* routes need in X-Hevn-Account when you read your own account; and HEVN_PUBLIC_KEY, the base64 public half of the PEM, which POST /dapi/v1/payouts takes as publicKey.
Nothing crosses between the two environments: developer keys, clients, tokens and rail ids are per-environment, and a sandbox token is refused in production.
The sandbox is the same API against one emulated partner on Base Sepolia. It runs on shared testnet money, so it is capped: at most 1 per payout, escrow or payin, a faucet that sends at most 5, only to a wallet holding less than 1, and 60 money calls per account per hour. Full table in Limits.

Ten steps

1

Log in

Two calls: POST /dapi/v1/auth/challenge returns a payload built by HEVN, and POST /dapi/v1/auth/token exchanges your signature over it for a session. The helpers this uses — load_key, public_key_b64, sign_bytes, sign_payload — are on Developer key and Signing.
Response
Keep both: export HEVN_ACCESS_TOKEN=… and export HEVN_USER_ID=cl_9f2c….The hevn / api client, key and poll_until in every tab below are the reference client — copy it once and the rest of this page is three lines a step.
2

Serve a page that opens the sign-in window

The window is opened by your page and answers to your callback page. For this quickstart both are static files. Save them in an empty folder and serve it on the origin you allowed:
index.html
callback.html
Open http://localhost:8080 in a browser. The popup opens straight from the click, which is what keeps the browser from blocking it. A real integration fetches the session URL from its own server inside that click instead of having you paste it — Sign in with HEVN has that version, and the cookie check this quickstart skips.
3

Create a link session

The session is about your own account, so it carries no X-Hevn-Account.
Response
The URL works for about ten minutes. 403 redirect_uri_not_allowed means http://localhost:8080 is not saved under Allowed sites. 403 client_creation_not_enabled means your account is not an active integrator yet; ask HEVN before you write any more code — see Going live.
4

Sign in as your customer

Paste the URL into the page and click Open HEVN. In the popup, sign in with the second Google account and choose Allow. The popup closes and the page shows what came back:
state is the one POST /connect/sessions answered. The code lives for five minutes.
5

Exchange the code for a client

Response
Keep the id: export HEVN_CLIENT_ID=cl_7YQ2Kf3mN8. If it says provisioning, read GET /dapi/v1/client with the id in X-Hevn-Account every two seconds until it is ready.
6

Fund the client's wallet

The sandbox mints emulated money. Without bankId this is a token transfer straight to the client’s wallet; the X-Hevn-Account header that northwind carries is what makes the call act for the client.
A 200 means the tokens landed; a 202 means they are on their way and the same request, with the same key, is safe to repeat. The faucet sends at most 5 per call, and only to a wallet that holds less than 1 of that token (Sandbox limits).
7

Read the balance you just created

/client/balance names no client in its path either: the header picks the account, and leaving it out is a 422 for a missing header rather than a read of your own wallet.
Response
That balance is read from Base Sepolia, not from a HEVN table.
8

Save a contact and book a payout

Pay the money to an address you control: your own account’s wallet. Read it with the same balance route, acting as yourself — the userId from step 1 goes in X-Hevn-Account, because that header is the only thing that selects an account on /client*. Then book 1.00 to it.
Response
authorization: "client" and no approval: this is the client’s money, so its holder signs it, not your key. Keep the id: export HEVN_PAYOUT_ID=po_6d21…. quickstart-payout-1 names this payment — re-run the call with the same key and you replay it; change the key and you book twice.
9

Approve it in the sign-in window

Create a sign session for the payout, paste its URL into the page and click Open HEVN again.
Sign in with the same second Google account. The window shows 1.00 USDC, the contact Treasury and your title, and the holder’s wallet signs the debit. The page then shows:
10

Read the payout and the ledger

The redirect said submitted. The payout read is the record:
Response
The ledger row carries its amounts as two sides — from is what left the source, to is what arrived — rather than a single amount. On this payout both are 1.000000 USDC, and the same 1 USDC is now in your own account’s balance: read it with the balance call from step 7, with $HEVN_USER_ID in X-Hevn-Account.

What just happened

  • Your customer owns the account. They created it in the sign-in window with their own Google sign-in, and allowed your product to act on it. You got a cl_… id, never their credentials.
  • Your key logged you in; it never touched their money. The payout was booked by you and signed by the holder’s own wallet. See Accounts and control.
  • The money is real testnet money. It moved on Base Sepolia; transactionHash is on chain.
  • Every constant came out of an earlier response. Client id, wallet address, contact id, payout id — nothing was invented.
  • One key was yours to choose: the Idempotency-Key. It names the payment, so a retry is the same payment. See Conventions.

What this quickstart did not do

It skipped the server half of the sign-in: binding the session’s state to the browser and keeping the client id in your own session. Do that before anything else — Sign in with HEVN. It never touched fiat either. Getting the client its own account details, and paying a bank account with a currency conversion, needs a client the partner has approved: the KYB document filled and its rail open. That is the next piece of work — Onboard a client, then Virtual accounts and Payouts.

Next: Accounts and control

Who owns a client account, and what your key can and cannot do.