Documentation

API errors

Every API v1 error carries a stable code, an HTTP status and a retry instruction; the code list is open, so your code must handle an unknown code by its HTTP status.

How to read an error

Every API error uses the same envelope, in REST and in MCP. The codes are the stable part; the text of message is written in Spanish, is meant for people and may change.

Error envelope
{  "ok": false,  "status": 400,  "request_id": "req_3z6y1wUd",  "error": {    "type": "invalid_request_error",    "code": "invalid_amount_format",    "message": "«abc» no es un monto válido. Usa un número positivo como texto con hasta 6 decimales, por ejemplo \"4.80\".",    "param": "amount",    "retry": "after_fixing",    "retry_after_ms": null,    "outcome_unknown": false  }}
Field
FieldWhat it is
`ok`Always false in an error.
`status`The HTTP status of the response.
`request_id`Request identifier; it also travels in the Request-Id header.
`error.type`The error family (authentication, permission, rate limit, idempotency, request, service).
`error.code`The stable code.
`error.param`The offending field, or null.
`error.retry`What to do with the same intent: no, as_is or after_fixing.
`error.retry_after_ms`Minimum wait before retrying, or null.
`error.outcome_unknown`true if the payment may have been made even though the call failed.

What `retry` means

  • no: Do not retry the request: it will not work on its own.
  • as_is: Retry the SAME request, with the same idempotency key, after Retry-After if there is one.
  • after_fixing: First fix what message and param say, then retry.

The code list is open

New codes can appear without changing the API version. Your code must not use a closed switch over error.code: handle an unknown code by its HTTP status and by error.retry.

Handle an unknown code
function handleError(status: number, error: { code: string; retry: string }) {
  switch (error.code) {
    case 'rate_limited':
      return waitAndRetrySameRequest();
    default:
      // Código nuevo o desconocido: decide por error.retry y por el estado HTTP.
      return error.retry === 'as_is' ? retrySameRequest() : showMessage();
  }
}

What to do with a code you do not know

  • 400, 404, 409, 413 and 422: do not retry on your own; show the message or escalate to a person.
  • 401 and 403: check the key and the permissions.
  • 429 and 5xx: retry the same request with the same idempotency key, with growing waits.

400 · The request is malformed

Today there are 53 codes, grouped by HTTP status.

invalid_json

The body is not valid JSON.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request

invalid_request

The request has an invalid value; param says which one.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

missing_parameter

A required field is missing; param says which one.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

unknown_parameter

A field the API does not know was sent (schemas do not allow extra fields).

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_amount_format

The amount is not a valid decimal string (up to 12 integer digits and 6 decimals, no sign or scientific notation).

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

amount_not_positive

The amount must be greater than zero.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

unsupported_currency

The currency is not supported (only usdc in this phase).

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_destination

The destination is not a valid domain, wildcard or 0x address.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

resource_required

A destination that is a domain requires resource (the exact URL you want to buy).

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

resource_not_allowed_for_address

A destination that is a 0x address is a transfer: it takes no resource.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_resource

resource must be https, with no credentials, no unusual port, up to 2048 characters, and with a body only on POST.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

resource_host_mismatch

The resource URL must be on the same domain as destination.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_memo

memo must be text of up to 280 characters.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_client_reference

client_reference must be text of up to 64 characters.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

missing_idempotency_key

The Idempotency-Key header is missing: it is required to create a payment.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_idempotency_key

The idempotency key must be 16 to 128 characters [A-Za-z0-9_-] (a UUID works) and not a toy value.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_pagination

limit (1-50), starting_after or ending_before are invalid.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_filter

A list filter has an invalid value.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

unsupported_version

The Nouron-Version value does not exist. Remove the header to use the one pinned to your key.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

invalid_policy

The rules sent have a malformed value; param says which one.

HTTP 400 · type invalid_request_error · retry: no · next: fix_request · param

401 · We do not know who is calling

missing_api_key

The Authorization: Bearer <api_key> header is missing.

HTTP 401 · type authentication_error · retry: no · next: verify_key

invalid_api_key

The key is not valid: check that it is complete, with no spaces or line breaks, and that it starts with np_test_ or np_live_.

HTTP 401 · type authentication_error · retry: no · next: verify_key

api_key_revoked

The key was revoked. Ask the owner for a new one under API keys.

HTTP 401 · type authentication_error · retry: no · next: verify_key

api_key_expired

The key expired. Rotate the key under API keys.

HTTP 401 · type authentication_error · retry: no · next: verify_key

403 · No permission

permission_denied

The key does not have permission for this operation.

HTTP 403 · type permission_error · retry: no · next: ask_owner_to_review

wrong_key_type

This operation requires another key type (agent or owner). The owner key is never pasted into an agent.

HTTP 403 · type permission_error · retry: no · next: use_other_key_type

read_only_key

The key is read-only and this operation writes.

HTTP 403 · type permission_error · retry: no · next: use_other_key_type

wrong_environment

The resource or the operation belongs to the other environment (test or live).

HTTP 403 · type permission_error · retry: no · next: verify_key

404 · Does not exist

not_found

That resource does not exist in this environment. With a live key, the simulation routes (/v1/test/*) do not exist either.

HTTP 404 · type invalid_request_error · retry: no · next: fix_request · param

409 · Conflicts with the current state

idempotency_conflict

You reused an idempotency key with a different request; changed_fields says what changed.

HTTP 409 · type idempotency_error · retry: no · next: new_attempt_needs_new_key · param

idempotency_key_in_use

Another request with the same key is still in progress. Retry unchanged after Retry-After.

HTTP 409 · type idempotency_error · retry: yes · next: retry_same_idempotency_key · Retry-After

cancel_too_late

The payment was already sent (processing) or settled: it cannot be cancelled.

HTTP 409 · type invalid_request_error · retry: no · next: check_status_later

spend_not_cancellable

The payment already ended (declined, failed, expired): there is nothing to cancel.

HTTP 409 · type invalid_request_error · retry: no · next: none

policy_version_conflict

The rules changed since you read them (expected_version does not match). Read them again.

HTTP 409 · type invalid_request_error · retry: no · next: fix_request · param

agent_name_taken

An active agent with that name already exists.

HTTP 409 · type invalid_request_error · retry: no · next: fix_request · param

agent_not_archivable

The agent has held or in-flight payments: wait for them to settle, expire or be cancelled.

HTTP 409 · type invalid_request_error · retry: no · next: check_status_later

413 · Body too large

payload_too_large

The body exceeds the maximum (16 KiB).

HTTP 413 · type invalid_request_error · retry: no · next: fix_request

422 · A product rule does not accept it

agent_limit_reached

The maximum of active agents was reached (5 in test, 10 in live).

HTTP 422 · type invalid_request_error · retry: no · next: ask_owner_to_review

key_limit_reached

An agent allows at most 3 active keys. Revoke or rotate one.

HTTP 422 · type invalid_request_error · retry: no · next: ask_owner_to_review

quota_exceeded

A usage cap of the test environment was reached (payments per owner, archived agents...). Reset the environment or ask for a review.

HTTP 422 · type invalid_request_error · retry: no · next: ask_owner_to_review

destination_wildcard_not_allowed

Wildcards over shared public suffixes (*.vercel.app, *.github.io...) are not allowed because they authorize third parties.

HTTP 422 · type invalid_request_error · retry: no · next: fix_request · param

destination_blocked

The destination is on Nouron's global block list and cannot be allowed.

HTTP 422 · type invalid_request_error · retry: no · next: fix_request · param

policy_inconsistent

The rules contradict each other (for example, the per-payment cap is above the daily one).

HTTP 422 · type invalid_request_error · retry: no · next: fix_request · param

agent_archived

The agent is archived and does not accept this operation.

HTTP 422 · type invalid_request_error · retry: no · next: ask_owner_to_review

capability_unavailable

The function is not available for the country or holder type, or does not exist yet. Defined in the contract; not returned yet.

HTTP 422 · type invalid_request_error · retry: no · next: not_available_in_country · reserved

verification_required

The operation needs a verification level the holder does not have yet; the owner completes it in the console. Defined in the contract; not returned yet.

HTTP 422 · type invalid_request_error · retry: no · next: complete_verification · reserved

account_on_hold

The operation cannot be completed right now; write to support with the Request-Id. Same text, shape and timing whatever the cause. Defined in the contract; not returned yet.

HTTP 422 · type invalid_request_error · retry: no · next: contact_support · reserved

429 · Too fast

rate_limited

Too many requests. Wait Retry-After and retry with exponential backoff and some jitter.

HTTP 429 · type rate_limit_error · retry: yes · next: retry_later · Retry-After

agent_busy

This agent already has a payment being decided; retry unchanged after Retry-After.

HTTP 429 · type rate_limit_error · retry: yes · next: retry_same_idempotency_key · Retry-After

500 · Nouron failure

internal_error

Our failure. Retry with the same idempotency key; if it persists, write to support with the Request-Id.

HTTP 500 · type api_error · retry: yes · next: retry_same_idempotency_key

503 · Service unavailable

service_unavailable

Service unavailable for a moment. Retry with the same key after Retry-After.

HTTP 503 · type api_error · retry: yes · next: retry_same_idempotency_key · Retry-After

platform_paused

Nouron paused the platform for safety. Payments are rejected until it resumes.

HTTP 503 · type api_error · retry: yes · next: contact_support · Retry-After

partner_unavailable

An external service (partner) is not responding. Retry after Retry-After. Defined in the contract; not returned yet.

HTTP 503 · type api_error · retry: yes · next: retry_later · Retry-After · reserved