Skip to content

Payments Direct 2.0 returns a standardized error response for every failed API request. Building a reliable integration means classifying errors correctly, retrying safely, and escalating promptly when retrying won't help.

This topic covers:

  • How to classify errors using the code and type fields
  • Which errors are safe to retry, and how to retry them
  • Recommended exponential backoff parameters
  • Handling authentication errors
  • Handling payment failures (FAILED, DECLINED, RETURNED states)
  • What to log and monitor

Classify before you act

Every error response includes a code field (for example, USR_067) and a type field (for example, USER_ERROR). Always use the code field as your primary signal, not the HTTP status code alone. Two errors can share an HTTP status but require completely different handling.

Error type reference

TypePrefixWhat it meansGeneral action
USER_ERROR or NOT_FOUNDUSR_The request itself is the problem: missing fields, invalid values, or a resource that doesn't exist.Fix the request and resubmit. Do not retry the same request.
AUTH_ERRORAUTH_The request was rejected due to an authentication or authorization problem.See Handling authentication errors below.
SYSTEM_ERRORSYS_An internal error occurred in Ripple's infrastructure.Retry with exponential backoff. Escalate to Ripple technical support if the condition persists.
CONFIGURATION_ERRORCFG_An account or service configuration issue prevents the request from completing.Do not retry. Contact Ripple technical support.

Transient vs. permanent errors

Before retrying, confirm that the error is transient (a condition that may resolve itself) rather than permanent.

Error typeHTTP statusRetryable?Recommended action
USER_ERROR400, 404, 415NoFix the request and resubmit.
USER_ERROR402Not until resolvedResolve the underlying condition (insufficient balance, credit limit, or past-due invoice) before retrying.
NOT_FOUND404NoVerify the resource ID and resubmit.
AUTH_ERROR401Yes (after token refresh)Regenerate your access token and retry.
AUTH_ERROR403NoVerify your token has the required scopes. Contact Ripple technical support if the issue persists.
SYSTEM_ERROR500Yes (with backoff)Retry with exponential backoff. Contact Ripple technical support if the issue persists.
CONFIGURATION_ERROR500NoContact Ripple technical support.

Retry strategy

Exponential backoff with jitter

When a request fails with a retryable error (SYSTEM_ERROR / 500, or AUTH_ERROR / 401 after a token refresh), use exponential backoff with jitter rather than retrying immediately or at a fixed interval. Immediate or synchronized retries amplify load on an already stressed system and can trigger rate limiting.

Recommended approach:

  1. On the first failure, wait a short base interval.
  2. On each subsequent failure, double the wait time.
  3. Add random jitter (±10–20% of the interval) to desynchronize retries across clients.
  4. Cap the maximum wait at a reasonable ceiling.
  5. After a configurable number of attempts, stop retrying and alert your on-call team.

Example backoff schedule:

Retry attemptBase waitWith jitter (±20%)
12s1.6s – 2.4s
24s3.2s – 4.8s
38s6.4s – 9.6s
416s12.8s – 19.2s
532s25.6s – 38.4s
6+60s (cap)48s – 72s

Use a maximum retry count

Set a hard limit on the number of retries (for example, 5 attempts). After that limit is reached without a successful response, stop retrying, record the failure, and alert your team. Continuing to retry indefinitely can mask a persistent issue and delay investigation.


Idempotency and safe retries

Before retrying a mutating request (such as creating a payment), check whether the original request may have been received and processed by Ripple despite returning an error. A network timeout, for example, does not mean the payment was not created.

Best practice: Use a client-assigned internalId or idempotency mechanism when creating payments. If you retry a payment creation request, include the same internalId as the original request. Ripple will return the existing payment if it was already created, preventing duplicate payments.

Do not blindly retry payment creation

If you receive a timeout or connection error on a create payment request, do not immediately retry without first checking whether the payment was created. Use GET /v3/payments with your internalId to check before submitting again.


Handling authentication errors

401 Unauthorized (AUTH_001, AUTH_003)

A 401 error typically means your access token is expired or invalid. Access tokens have a 1-hour TTL.

Recommended handling:

  1. Generate a new access token using your client_id and client_secret.
  2. Retry the original request with the new token.
  3. Do not cache tokens beyond their expires_in value.

For guidance on token generation and caching, see Authentication.

403 Forbidden (AUTH_002)

A 403 error means your token is valid but lacks the required scopes for the requested operation.

Recommended handling:

  • Do not retry with the same token. A new token with the same credentials will have the same scopes.
  • Review the required scopes for the operation in the API reference.
  • Contact Ripple technical support if you believe your credentials should have the required permissions.

403 Unauthorized (AUTH_051)

AUTH_051 occurs when a request references a payment created by a different organization. This is a permanent error. Do not retry.


Handling payment failures

Payment failures are distinct from API errors. A payment failure occurs after a payment is created successfully (HTTP 201) but later transitions to a terminal state of FAILED, DECLINED, or RETURNED. These are not errors in the API response. They are paymentState values you observe when polling or receiving webhooks.

How to detect a payment failure

Payment failure details, including the error code and reason, are available on the payment object at GET /v3/payments/{paymentId} after the payment reaches a terminal state. Webhook payloads include the new paymentState but not the error code. Always fetch the full payment record to get failure details.

Terminal states

StateRetryable?Action
FAILEDPossiblyFetch the payment record to get the error code. Check the API payment failures reference and API error codes reference for the specific code. Some FAILED states are caused by transient issues and can be retried with a new payment; others indicate a permanent condition.
DECLINEDNot until resolvedFetch the payment record to get the error code. DECLINED usually indicates a business rule violation or account condition (insufficient balance, credit limit, etc.) that must be resolved before resubmitting.
RETURNEDConsult RippleThe payment was returned by a downstream institution after completing. This is not a retry scenario. Contact Ripple technical support to investigate the return reason.

For a full list of payment failure codes and their descriptions, see API payment failures.

For background on payment states and the payment lifecycle, see Payment states.


What to log and monitor

Log the following fields from every error response:

  • code — the specific error code; use this for alerting rules and dashboards
  • type — the error category; use this to route to the correct handler
  • status — the HTTP status code
  • timestamp — the time the error occurred in the upstream system
  • The API endpoint and HTTP method that returned the error
  • Your request ID or correlation ID (if your integration generates one)

Alerting recommendations

ConditionAlert priority
Any CONFIGURATION_ERROR (CFG_)High — these require Ripple involvement and will not self-resolve
Repeated SYSTEM_ERROR (SYS_) from the same endpointMedium — investigate after retry budget is exhausted
AUTH_ERROR 403 (AUTH_002, AUTH_051)Medium — may indicate a configuration change or credential scope issue
Sustained USER_ERROR 402 (USR_062USR_067)Medium — indicates an account condition (balance, limits, invoice) requiring attention

Next steps