Authentication
API Key
Pass your API key in the
X-API-Key
header:
X-API-Key: mcp_<your_key>
API keys are created through the dashboard. Each key can optionally have:
-
IP restriction
— comma-separated list of allowed IPs. Requests from other IPs
are rejected with
403. -
Spend limit
— maximum cumulative USD amount that can be transferred with
this key. Once exceeded, further transfers are rejected with
403.
The raw key is shown only once at creation. Only a SHA-256 hash is stored on the server.
Get Balance
/mcp/get_balance
Returns the balance and account info for the API key owner.
Response
{
"balance": 150.25,
"email": "[email protected]",
"address": "abc123.v0.hevn.tg"
}
| Field | Type | Description |
|---|---|---|
balance |
number | USD balance |
email |
string | Account email |
address |
string | null | NEAR intents address |
Transfer USD
/mcp/transfer_to_user
Transfer USD from your balance to a recipient on Base. If the recipient doesn't have a HEVN account, one is created automatically.
Request body
{
"email": "[email protected]",
"amount": 10.0
}
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | yes | Recipient email (Gmail or Google Workspace only) |
amount |
number | yes | USD amount to send |
@gmail.com
) and Google Workspace email addresses are supported. Emails on
other providers will be rejected with
400
.
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Idempotency-Key |
string | no | Unique key to prevent duplicate transfers. If a request with the same key was already processed, the original response is returned. |
Response
{
"quoteId": "quote_abc123",
"intentHash": "hash_xyz",
"nearTx": "tx_near_123",
"userCreated": false
}
| Field | Type | Description |
|---|---|---|
quoteId |
string | Transfer ID — use to poll status |
intentHash |
string | null | NEAR intents transaction hash |
nearTx |
string | null | NEAR blockchain transaction hash |
userCreated |
boolean |
true
if a new account was created
|
Errors
| Code | Detail |
|---|---|
400 |
Insufficient balance |
403 |
Spend limit exceeded |
404 |
Sender wallet not found |
Get Transfer Status
/mcp/transfer/{quoteId}/status
Check the current status of a transfer by its
quoteId
.
Response
{
"quoteId": "quote_abc123",
"status": "CONFIRMED",
"intentHash": "hash_xyz",
"nearTx": "tx_near_123",
"destinationTx": "0xabc...",
"refundTx": null,
"amountIn": "10000000",
"amountOut": "9950000",
"errorMessage": null
}
| Field | Type | Description |
|---|---|---|
quoteId |
string | Transfer ID |
status |
string | Current status |
intentHash |
string | null | NEAR intents transaction hash |
nearTx |
string | null | NEAR blockchain transaction hash |
destinationTx |
string | null | Base blockchain transaction hash |
refundTx |
string | null | Refund transaction hash |
amountIn |
string | null | Raw input amount (6 decimals) |
amountOut |
string | null | Raw output amount (6 decimals) |
errorMessage |
string | null | Error details (if failed) |
Transfer statuses
| Status | Description |
|---|---|
PENDING |
Submitted, awaiting processing |
CONFIRMING |
Cross-chain swap in progress |
CONFIRMED |
Completed successfully |
FAILED |
Failed (see
errorMessage
)
|
EXPIRED |
Expired before completion |
List Transfers
/mcp/transfers
Get the history of transfers made with your API key.
Query params
| Param | Type | Default | Description |
|---|---|---|---|
limit |
int | 50 | Items per page (1–200) |
offset |
int | 0 | Items to skip |
Response
[
{
"trxHash": "tx_near_123",
"amount": 10.0,
"receiverEmail": "[email protected]",
"receiverAddress": "0x1234...abcd",
"transactionLink": "https://basescan.org/tx/0xabc...",
"time": "2026-03-04T12:00:00Z"
}
]
| Field | Type | Description |
|---|---|---|
trxHash |
string | NEAR transaction hash |
amount |
number | null | USD amount sent |
receiverEmail |
string | null | Recipient email |
receiverAddress |
string | null | Recipient EVM address on Base |
transactionLink |
string | null | Basescan link |
time |
string | ISO 8601 timestamp |
Error Handling
All errors return JSON with a
detail
field:
{ "detail": "Error description" }
| Code | Meaning |
|---|---|
400 |
Bad request — insufficient balance, missing data |
401 |
Invalid or missing API key |
403 |
IP not allowed or spend limit exceeded |
404 |
User, wallet, or transaction not found |
502 |
External service error |
Best Practices
Always use Idempotency-Key
Always send the
Idempotency-Key
header with every
POST /mcp/transfer_to_user
request. Generate a deterministic, reproducible key for each
transfer — for example, a hash of sender + recipient +
amount + date, or a UUID that you persist before making the
request.
This prevents double spending if a request is retried due to network errors, timeouts, or client-side retries. If the server has already processed a request with the same key, it returns the original response instead of creating a duplicate transfer.
curl -s -X POST https://api.gethevn.com/api/v1/mcp/transfer_to_user \
-H "X-API-Key: mcp_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: tx-alice-bob-10usd-20260306" \
-d '{"email":"[email protected]","amount":10.0}'
Check balance before transferring
Always call
GET /mcp/get_balance
before initiating a transfer to verify sufficient funds and
avoid
400
errors.
Poll status until terminal state
After initiating a transfer, poll
GET /mcp/transfer/{quoteId}/status
every 3–5 seconds until the status reaches a terminal
state:
CONFIRMED
,
FAILED
, or
EXPIRED
. Do not assume success from the initial
200
response alone.
Retry safely with Idempotency-Key
On
502
errors or network timeouts, retry the request with the
same
Idempotency-Key
. The server will return the original response if the transfer
was already processed, so retries are safe.
Use spend limits on API keys
Configure a spend limit for each API key in the dashboard to cap maximum exposure and protect against runaway automation.