API Reference
Naven MPP Relay endpoints, public access, and response formats.
Base URL
https://mpp.naven.networkThe relay is a server-to-server API. Canonical lifecycle routes use the
/v1/mpp prefix.
Public access
All endpoints are currently public. No Naven account, API key, or onboarding approval is required. Lifecycle calls must still contain a valid buyer-signed MPP credential, and broadcast calls require an idempotency key.
Endpoints
| Method | Path | Access | Description |
|---|---|---|---|
GET | /health | Public | Check relay availability |
GET | /supported | Public | List supported methods and assets |
POST | /v1/mpp/validate | Public | Validate without broadcasting |
POST | /v1/mpp/broadcast | Public | Validate and settle the authorization |
Supported capabilities
GET /supported{
"methods": [
{
"method": "evm",
"intent": "charge",
"credentialTypes": ["authorization"]
}
],
"assets": [
{
"network": "eip155:4663",
"chainId": 4663,
"address": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
"symbol": "USDG",
"decimals": 6,
"maxTimeoutSeconds": 300
}
]
}Treat this response as the current capability declaration instead of hard-coding future network or asset support.
Request body
Both lifecycle endpoints accept the same JSON object. The maximum body size is 64 KiB.
| Field | Required | Description |
|---|---|---|
credential | yes | Parsed MPP credential object or serialized Payment ... credential |
request | yes | Canonical atomic-unit evm/charge request from the server method hook |
{
"credential": {
"challenge": {},
"payload": {},
"source": "did:pkh:eip155:4663:0x..."
},
"request": {
"amount": "10000",
"currency": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
"recipient": "0x...",
"methodDetails": {
"chainId": 4663,
"credentialTypes": ["authorization"],
"decimals": 6
}
}
}The request must exactly match the request embedded in the credential's
challenge. The merchant server must independently verify the challenge HMAC and
route binding before accepting the payment.
Validate
POST /v1/mpp/validate
Content-Type: application/jsonValidation is advisory and never submits a transaction:
{
"success": true,
"accepted": true,
"method": "evm",
"intent": "charge",
"source": "did:pkh:eip155:4663:0x...",
"details": {
"challengeId": "...",
"network": "eip155:4663",
"chainId": 4663,
"currency": "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
"symbol": "USDG",
"decimals": 6,
"amount": "10000",
"recipient": "0x...",
"payer": "0x..."
}
}An accepted validation can still fail later if the authorization expires, is used elsewhere, or the payer's balance changes. Broadcast is the terminal acceptance step.
Broadcast
POST /v1/mpp/broadcast
Idempotency-Key: <credential-specific-key>
Content-Type: application/jsonIdempotency-Key must contain 8 to 200 characters. Retrying the same credential
with the same key returns the same in-flight or completed result. Reusing that key
for a different request returns 409 Conflict.
Successful settlement returns an MPP receipt:
{
"success": true,
"receipt": {
"challengeId": "...",
"chainId": 4663,
"method": "evm",
"reference": "0xTransactionHash",
"status": "success",
"timestamp": "2026-09-10T12:00:00.000Z"
}
}Attach this receipt to the merchant's final response with mppx; do not treat a
successful call to /validate as settlement.
Errors
Errors use a stable code and message:
{
"error": {
"code": "invalid_idempotency_key",
"message": "Idempotency-Key must contain between 8 and 200 characters"
}
}Validation failures also include "success": false and "accepted": false.
| HTTP | Common codes | Meaning |
|---|---|---|
400 | invalid_json, invalid_request, invalid_credential, invalid_payment_request, invalid_idempotency_key | Request shape or required header is invalid |
409 | idempotency_conflict | The key was already used for different payment data |
413 | request_too_large | JSON body exceeds 64 KiB |
422 | unsupported_method, unsupported_asset, request_mismatch, challenge_binding_mismatch, invalid_signature, authorization_already_used, insufficient_balance | Payment is unsupported or cannot currently settle |
500 | internal_relay_error | Relay could not process the request |
503 | idempotency_capacity_exceeded | Relay is temporarily unable to accept another broadcast |
For an expired or rejected credential, issue a fresh MPP challenge rather than retrying the same authorization with a new idempotency key.