https://sandbox-api.nuvante.ioErrors
Handle structured API errors
When a request fails, the response contains an errors array. Build your error handling around the stable code values, because message text can change.
Error envelope
{
"errors": [{
"code": "example_code",
"message": "Human-readable explanation",
"type": "invalid_request_error",
"param": "optional_field",
"docUrl": "https://www.nuvante.io/developers/docs/errors#example_code"
}],
"meta": { "commandId": "…" }
}Documented error codes
invalid_api_key401The API key is invalid or has been revoked.unauthorized401The Authorization header is missing or malformed.invalid_idempotency_key409The Idempotency-Key header is invalid.idempotency_key_reused409The Idempotency-Key was already used with a different request.idempotency_key_in_progress409The original request is still being processed.invalid_request400The Nuvante-Version header is invalid.bad_request400A header, path, query or JSON body failed validation.invalid_amount_precision400An amount has more decimal places than the asset or RTGS allows.forbidden403The caller doesn't have the required participant kind or capability.not_found404The resource doesn't exist, or the caller can't see it.conflict409The request is valid but can't run given the current data or state.mandate_rejected403The agent mandate check failed, so the agent isn't authorised to do this.rate_limit_error429Too many requests. Back off and retry with an exponential delay.sandbox_unavailable503This feature only exists in sandbox.upstream_unavailable503A chain read or upstream service call failed.internal_error500Something unexpected went wrong on our side. It's safe to retry an idempotent request after a short wait.Every error code the engine route handlers return
| Value | Description |
|---|---|
bad_request | The request failed validation. |
conflict | The operation conflicts with the current state. |
forbidden | The caller doesn't have the required permission or capability. |
not_found | The resource wasn't found. |
unauthorized | Credentials are missing or invalid. |
invalid_api_key | The API key is invalid, revoked or expired. |
invalid_request | The request structure is invalid. |
invalid_idempotency_key | The idempotency key isn't a valid UUID. |
idempotency_key_reused | The idempotency key was used with different parameters. |
idempotency_key_in_progress | A request with this idempotency key is already being processed. |
sandbox_unavailable | This sandbox-only feature isn't available here. |
upstream_unavailable | A read from the chain or an upstream service failed. |
internal_error | Unexpected server error. |
bad_gateway | An upstream service returned an error. |
agent_not_found | The agent wasn't found. |
mandate_rejected | The agent mandate check failed. |
invalid_amount_precision | The amount has more decimal places than the issuer's declared precision. |
invalid_proof | The reserve proof artifact failed verification. |
invalid_amount_precision vs bad_request
Both of these are 400s, and the line between them is clear. You get bad_request when the JSON body fails Zod schema validation, for example a wrong type, a missing field or an empty string. It always means something is wrong with the structure. You get invalid_amount_precision when the amount is well formed but has more decimal places than the issuer allows (for example, amountPrecision: 2 and you sent "100000.001"). Route the two differently using the code.
Fields
Every error has a code and a message. Some also include a type. Depending on the error, you may also get param, detail and a docUrl.
Transaction conflicts
Transaction-specific error conditions
| Condition | Result | Notes |
|---|---|---|
| Duplicate paymentReference | 409 conflict | Your participant has already used this business reference. |
| Not enough source balance | 409 conflict | The source wallet can't cover the requested amount. |
| Unknown issuer or asset | 409 conflict | We can't find the source or target issuer, the issuer has no reserve account, or the target asset isn't registered. |
| Unsupported issuer mode | 409 conflict | The issuer's profile needs Mode 3, and the mandatory refund contract isn't in place. |
| Cancellation not allowed | 409 conflict | The transaction is past the burn, settlement is under way, a cancellation is already running, or its state doesn't allow cancelling for another reason. |
| Malformed transaction ID | 404 not_found | Get and cancel return 404 for malformed UUIDs on purpose, so we don't leak any information. |
Failed transactions are success responses
A transaction that's rejected, fails, is cancelled or parks still comes back as a normal 200. Check lifecycleStatus, parked, terminal and details.reason to see what happened. Outcomes from the saga always arrive in the transaction resource and never as HTTP error envelopes.
