Authentication
Every /v2* request needs an API key, except GET /health and GET /openapi.json. Send the key in the x-api-key header.
GET /transfers
x-api-key: sk_test_a1b2c3...
The header is evaluated as the credential, not a cookie. Even if the browser sent a session cookie, an API key must be present.
Key format
Keys self-identify their environment by prefix:
| Prefix | Environment |
|---|---|
sk_test_ | Testnet |
sk_live_ | Mainnet |
A key is 64 random characters after the prefix, for example sk_live_0f9a....
Environment binding
A test key works on testnet chains. A live key works on mainnet chains. The API enforces this on POST /transfers; using the wrong key for a chain returns 403.
{
"code": "CHAIN_NOT_ALLOWED_FOR_KEY_ENVIRONMENT",
"message": "Chain 1 is not allowed for test API keys.",
"chainId": 1,
"keyEnv": "test"
}Use sk_test_ keys for development against testnets. Use sk_live_ keys for production traffic.
Authentication errors
| Status | Code | When |
|---|---|---|
| 401 | INVALID_API_KEY | No x-api-key header. |
| 403 | INVALID_API_KEY | Key is invalid, expired, disabled, or belongs to a deleted user. |
Returned as { "code": "...", "message": "..." }.
Rate limits
The default limit is 50 requests per minute per key. When you exceed it, the API returns 429. Wait the value of the Retry-After header, then retry.
{
"code": "RATE_LIMITED",
"message": "...",
"details": { "tryAgainIn": 30 }
}Note that the rate-limit body is the plugin's own shape, not the { code, message } contract used by the 401/403 responses.
Getting a key
Sign in to your Mure account in a browser, then create a key from that session:
POST /auth/api-key/create
The request body carries the key name.
{
"name": "production"
}The response contains the full key once. Copy it now; it is not shown again. The key is stored as a hash, so Mure cannot recover it if you lose it. Delete and recreate a key to rotate it.