Skip to content

Errors

Every error response is an RFC 7807 problem document. The HTTP status tells you the broad category; the body tells you exactly what happened.

The shape

{
"type": "https://errors.paylera.io/payments/requires_action",
"title": "Payment requires customer action",
"status": 200,
"detail": "The payment method requires 3DS authentication.",
"instance": "/v1/invoices/inv_…/pay",
"problem": "payment.requires_action",
"trace_id": "01H8MZP…",
"errors": [ ],
"next_action": { }
}
FieldMeaning
typeA stable URL identifying the problem class. May be dereferenced for documentation.
titleA short human-readable summary.
statusThe HTTP status code.
detailA human-readable explanation specific to this occurrence. May vary across calls.
instanceThe URL path of the request.
problemA stable string discriminator your code branches on. Use this, not type or title.
trace_idThe request’s trace ID. Include in support tickets.
errorsOptional array of field-level validation errors.
next_actionOptional structured payload pointing at the resolution (used by some 200 responses, not just errors).

Status codes

CodeWhen
200Success. May still carry a structured next_action (e.g., requires_action).
201Resource created.
202Accepted; will complete asynchronously.
204Success, no body.
400Malformed request.
401Authentication failed.
403Authenticated, but not allowed (scope, AAL, ownership).
404Resource doesn’t exist (or isn’t visible to your tenant).
409Conflict — usually a state-machine violation.
410Gone — resource existed but was permanently removed.
422Validation failed. See errors[].
429Rate limited. See Retry-After.
500An unexpected error on our side.
503Temporary unavailability — typically a downstream provider.

Branch on problem, not status

status tells you broadly. problem tells you exactly. Two 422s with different problems mean different things:

{ "status": 422, "problem": "subscription.commitment_active" }
{ "status": 422, "problem": "subscription.proration_invalid_currency" }

Use problem in switch statements; use status for fallback / metric labels.

Field-level errors

For 422s with multiple invalid inputs:

{
"status": 422,
"problem": "validation.failed",
"errors": [
{ "field": "billing_address.country", "code": "country.invalid", "message": "Must be ISO-3166 alpha-2." },
{ "field": "name", "code": "required", "message": "Required." }
]
}

Render message to the user; key off code for client-side handling (showing inline validation, focus management).

Idempotent replays

Replays of an idempotent request return the original response verbatim — including 4xx errors. If your first call returned a 422, the retry returns the same 422. If you want a different outcome, send a new idempotency key.

Trace IDs

Every response includes trace_id. Include it when you contact support; we can pull the request’s full trace from observability with that single ID.

Common errors by category

problemWhen
auth.*Authentication failures. See Authentication.
idempotency.requiredA money-moving / resource-creating route was called without Idempotency-Key.
idempotency.body_mismatchThe same key was sent with a different body.
validation.failedOne or more fields invalid. See errors[].
subscription.*FSM transition not allowed; see Status reference.
invoice.lockedMutation attempted on a non-draft invoice.
payment.requires_action3DS / SCA needed. See next_action.
payment.declinedProvider declined the charge; see last_error.
wallet.insufficient_fundsWallet balance below requested amount.
fx.stale_rateFX rate older than the staleness threshold.
tax.engine_unavailableTax engine returned an error; finalisation rolled back.
rate_limit.exceededToo many requests; back off per Retry-After.

The full list lives in the Error code reference.

What you should log

For every error response your client sees:

  • HTTP status
  • problem
  • trace_id
  • The endpoint and method

This combination is searchable end-to-end. Body payloads may contain PII; redact before logging.