Skip to main content

Base URL

/api/v1

Authentication

All API endpoints require an API key. Pass it via the x-api-key header or as a Bearer token.
# Header authentication
x-api-key: mh_live_abc123...

# Or Bearer token
Authorization: Bearer mh_live_abc123...
API keys are prefixed to indicate mode:
PrefixMode
mh_test_Test mode — uses test accounting
mh_live_Live mode — uses live accounting
The Solana cluster (mainnet/devnet) depends on the environment the API is deployed against.

Request format

Use JSON request bodies for POST requests and standard path/query parameters for GET and DELETE requests.
Content-Type: application/json

Idempotency

All POST mutations require an Idempotency-Key header (8–64 characters, [a-zA-Z0-9._-]). Use a random UUID per request. Reusing a key with a different body returns MH_071.
Idempotency-Key: a3f8c2e1-74b9-4d06-9832-15f0e7b3a129
CodeDescriptionStatus
MH_070Idempotency-Key header missing or invalid400
MH_071Idempotency-Key reused with different request body409
MH_072Idempotency-Key request still in progress409

Error codes

All errors include a structured MH_XXX code for programmatic handling.

Authentication

CodeDescriptionStatus
MH_001Invalid or missing API key401
MH_002API key revoked401
MH_003Integration suspended403
MH_004Rate limit exceeded429

Validation

CodeDescriptionStatus
MH_010Unsupported token mint or missing pricing context400
MH_011Invalid wallet address400
MH_012Amount below minimum400
MH_013Hops out of range (3–10)400
MH_014Arrival time below minimum for hop count400
MH_015Invalid external ID format400

Transfer lifecycle

CodeDescriptionStatus
MH_030Transfer not found404
MH_031Route creation failed500
MH_032Funding not completed within timeout408
MH_033Transfer already exists (duplicate externalId)409
MH_034Transfer expired410
MH_035Transfer not in a state that allows broadcast confirmation409
MH_036Broadcast signature not found on chain404
MH_037Broadcast transaction failed on chain422
MH_038Broadcast transaction did not invoke the MultiHopper program422
MH_039Keeper funding signature required but not provided400

Webhooks

CodeDescriptionStatus
MH_050Webhook URL unreachable400
MH_051Max webhook endpoints reached400

Recovery

CodeDescriptionStatus
MH_080Recovery action not allowed in current transfer phase409
MH_081Nothing to rescue — no rescuable accounts found409
MH_082Nothing to reclaim — no reclaimable rent found409
MH_083Provided rescue signatures do not match the prepared bundle400

Reward claims

CodeDescriptionStatus
MH_060Below minimum claim threshold400
MH_061Rewards wallet not set400

Internal

CodeDescriptionStatus
MH_090Internal server error500
MH_091Service temporarily unavailable503

Rate limits

Rate limits are enforced per API key, per endpoint. When exceeded, the API returns MH_004 with a Retry-After header.
EndpointLimitWindow
POST /transfers10 req60s
POST /transfers/:id/funding/refresh10 req60s
POST /transfers/:id/funding/confirm10 req60s
POST /transfers/estimate30 req60s
GET /transfers/:id60 req60s
GET /transfers60 req60s
POST /webhooks30 req60s
GET /webhooks30 req60s
DELETE /webhooks/:id30 req60s
GET /usage30 req60s

Pricing

Pricing tiers are determined by the USD equivalent of the transfer at quote time. For native SOL, the backend resolves USD value from CoinGecko spot pricing. Fees are split between you (the integrator) and the platform.

Estimate fees

Check costs before creating a transfer.

Create transfer

Create a transfer and receive funding transactions.

Webhooks

Receive real-time transfer lifecycle events.

Usage

View usage and fee summaries for your integration.