/dapi/v1 and signs payments from your integrator account. Create it in the HEVN app, then log in with POST /dapi/v1/auth/challenge and POST /dapi/v1/auth/token.
Developer key
Create it in the app
No route creates a key, in/dapi/v1 or in the app’s API (/api/v1).
- Sign in to
https://sandbox.gethevn.com, orhttps://app.gethevn.comfor production. Go to Settings → Partner program → Developer. - Enter the IP allowlist. It cannot be changed after creation.
- Save the private key. The browser generates the keypair and shows the private half once, and HEVN stores the public half. Write the private half to a file with mode
0600on the machine that uses it.
Key format
The curve is P-256, also calledsecp256r1 or prime256v1. The app shows the key’s dk_… id and its fingerprint, sha256:<hex of sha256(DER)>. The public key is sent as base64 of the DER SubjectPublicKeyInfo, at most 4096 characters. The wire formats of the key and the signature are in Signature format and on Start a developer-key login.
The IP allowlist
Include the addresses an autoscaler adds. Your edge must remove caller-supplied
X-Forwarded-For, X-Real-IP and CF-Connecting-IP headers. Otherwise the caller controls the address that is checked.
Load the key
Read the key from the file named inHEVN_KEY_PEM. The loader is in HTTP client. A 200 from POST /dapi/v1/auth/challenge shows that the key exists and the allowlist covers the host.
What a session from the key may do
A session from any of your keys can call any/dapi/v1 route. A key has no scopes.
The key signs for your integrator wallet and for your sub accounts. It does not sign for a client’s wallet or for an external account. See Who can spend.
Sessions
A session is an access token and a refresh token issued to your developer key.Log in
Sign this proof string with your developer key:POST /dapi/v1/auth/challenge. The field rules are on Start a developer-key login.
Response
payload, sign the bytes as in Signing, and call POST /dapi/v1/auth/token:
Response
userId is the cl_… id of your integrator account. Use it wherever a client id is accepted. The challenge refusals and the one-call login form are on Exchange a signed login challenge.
When a key is refused
At login,401 invalid_credentials covers any problem with the email, the key, the allowlist, the signer or the signature. It does not name the check that failed.
Refusals after login are in Errors:
403 forbidden(key deleted, address outside the allowlist, ordetails.reason = "developerSessionRequired") is under Developer keys.403 key_not_registered,409 signer_not_attachedand400 signature_invalidare under Authentication and signing.403 account_not_controlledis under Acting as a client.
Tokens
The access token audience isplatform, and the refresh token audience is platform-refresh. Lifetimes and token fields are on Exchange a signed login challenge.
Both tokens have a developer_key_id claim that names the key behind the session. /dapi/v1 refuses other bearers.
- No bearer returns
401 unauthenticated. - An app token, a refresh token on another route, or a token with no key behind it returns
403 forbidden.details.reasonisdeveloperSessionRequired.
/api/v1, the app’s API, refuses a platform token.
Refresh with the refresh token as the bearer and an empty body:
Response
Session in HTTP client does this.
Session scope
Production refuses a sandbox token, and the reverse. Log in on each host with a key created in that environment’s app. See rate limits.Acting as a client
SendX-Hevn-Account: cl_… with your access token to act for a client. One token covers all your clients: those linked through HEVN Connect and those created with POST /dapi/v1/clients for external wallets.
The header selects whose data a call reads and writes. It does not let the developer key sign for that client’s wallet.
{clientId} parameter.
Your own cl_… id, the userId from POST /dapi/v1/auth/token, selects your integrator account. Send it on the routes that require the header, for example to open a sub account with POST /dapi/v1/client/accounts.
For an access token that acts for one client, send its
userId to POST /dapi/v1/auth/refresh.
Rotate a key
Both keys work while both exist.1
Create the second key
Create it in the app, with an allowlist that covers the hosts that will use it.
2
Switch your servers
Deploy the new key file. Payments now send the new
publicKey. An approval is bound to your signer, so one prepared before the switch can be confirmed with either key.3
Delete the old key
Delete it in the app. The next login or payment that uses it is refused.
403, and so does POST /dapi/v1/auth/refresh. Delete the key when a token leaks, too. Test rotation in the sandbox.