Skip to main content
All routes on this page take a remote transfer key in X-Api-Key and answer JSON with camelCase keys. Amounts are USDC on Base, as decimal numbers.
The same routes are also served under /api/v1/mcp, the feature’s former name. That prefix is deprecated and kept only for existing integrations; use /api/v1/remote_spend_limit.

Get balance

GET /get_balance reads your smart wallet’s USDC balance and what this key may still spend in the current period, both live from the chain.
404 Smart wallet not found if the account has no smart wallet yet.

Resolve address

GET /resolve_address?email= returns the Base smart wallet that belongs to an email address.
If the email has no HEVN account, HEVN creates one and records its wallet address, which only the owner of that email can ever control — see deterministic addresses. The lookup counts against the rate limit.

Transfer

POST /transfer pays something your account already knows about: a contact, an invoice addressed to you, or a payout quote you created. Send exactly one of contactId, invoiceId or quoteId. None of them is 422. If you send more than one, invoiceId wins over quoteId, and quoteId over contactId. Header Idempotency-Key is optional. It is the deduplication reference only when the body has no invoiceId or quoteId, so send it on every contact transfer — see A transfer runs at most once.
200 OK:
txHash is the onchain transaction. userCreated and emailSent are always false on this route. Where the money goes: Errors specific to this route:

Transfer to an email address

POST /transfer_to_user pays any email address. If the email has no HEVN account, HEVN creates one, sends the money to its wallet and emails the owner an invitation to claim it. An existing account gets a payment-received email. Header Idempotency-Key is required; without it the request is 422.
Retrying with the same Idempotency-Key replays: the response carries the recorded txHash and nothing is sent again. On a replay userCreated and emailSent are false. Every new transfer also saves the receiver as one of your contacts.

List transfers

GET /transfers lists the transfers this account made through POST /transfer_to_user, newest first. Transfers made through POST /transfer appear in the app’s transaction history, not here.
receiverEmail holds the name saved on the contact: the receiver’s full name when their account has one, otherwise their email address.

Errors

Every refusal has one body:
detail is a human-readable sentence. Branch on the status code, and log detail.

Back to the overview

How keys, spender wallets and spend permissions fit together.