/dapi/v1 is a JSON envelope with a stable code. Branch on error.code and do not parse message.
Each response has an
X-Request-ID header. Log it and quote it to support. The HTTP client maps the envelope to a typed error.
Field errors
422 validation_failed names each failed field in wire spelling.
An unknown key returns field code
extra_forbidden.
Status codes
A status with no narrower slug returns the generic slug.
HEVN does not return
502. A 502 with an HTML body comes from the network in front of the API and has no slug. Treat it as a timeout.
A slug marked “Reserved” is in the published enum, but the API does not return it yet.
Request and transport
Authentication and signing
Developer keys
/dapi/v1 returns neither developer_key_* slug. The app’s key-management routes under /api/v1 use an owner session and a different error shape.
Acting as a client
Clients and sign-in window
The window’s callback codes are not error slugs. See Sign in with HEVN.
Rails and payins
Payouts
Contact, payout booking and swap routes return these slugs. Confirm errors are under Funding a payment.payout_not_fundable with details.reason holder_signature_unsupported means the holder cannot approve an FDIC_USD payout in the sign-in window. A contact on another chain or token without routing returns 409 payout_not_fundable.
account_unavailable on FDIC_USD means the client has no balance held at the partner bank. account_not_supported means a payin cannot settle into FDIC_USD, or a payout from it does not use the rail that holds it.
Accounts
/dapi/v1/client/accounts, and each route that takes an acc_… id, returns these slugs. Accounts compares the two kinds.
A sub account requested for a client returns
403 account_not_controlled (Acting as a client). POST /dapi/v1/payouts/{payoutId}/confirm on a payout with authorization: "wallet" returns 400 invalid_request with details.reason = "funded_by_wallet_transfer".
An accountId with another prefix returns 400 invalid_id. A sourceAccount or destinationAccount that is neither an account key nor an acc_… id returns 422 validation_failed.
Contact blockers
GET /dapi/v1/contacts/{contactId}/capabilities returns blockers[]. An entry has code, message and sometimes field. Blocker codes do not appear as error.code.
Funding a payment
POST /dapi/v1/payouts/{payoutId}/confirm returns these slugs. The sandbox settlement routes also return quote_not_submitted and payout_not_fundable. See Retrying a confirm.
KYB and documents
Escrow
Escrow confirms also return410 approval_expired and 409 approval_consumed. An unclassified deal error returns 409 conflict.
A closed window, or an over-large capture or authorize, returns 400 invalid_request with no details. Read the deal and choose from availableActions.
Escrow
insufficient_funds sets details.party to payer (authorize, charge) or operator (refund), with token, balanceAtomic and amountAtomic.