Skip to main content
ReconLayer returns errors as JSON objects with a machine-readable error code and, in most cases, a human-readable message. Some errors add extra fields — issues for validation failures, or extra context fields for domain-specific conflicts.

Error envelope

{
  "error": "string",
  "message": "string",
  "issues": [ { "path": ["field", "name"], "message": "string" } ],
  "details": { },
  "upstreamStatus": 0
}
error
string
required
Machine-readable error code. Stable — safe to branch on in client code. See the catalog below.
message
string
Human-readable description of what went wrong. Present on most errors; not guaranteed to be stable wording.
issues
array
Present on invalid_request. Each item has a path (array of field-name segments locating the offending field) and a message.
details
object
Present on some errors with extra structured context (e.g. conflict details).
upstreamStatus
integer
Present on errors that proxy a failure from an upstream provider, indicating the upstream’s HTTP status.

Validation errors — 400 invalid_request

Request bodies and query strings are validated against the API’s schemas. A validation failure returns 400 with error: "invalid_request" and an issues array:
400 Invalid request body
{
  "error": "invalid_request",
  "issues": [
    {
      "path": ["sourceAmount"],
      "message": "must match pattern \"^-?\\d+(\\.\\d+)?$\""
    }
  ]
}
Each issue’s path is the segment path to the offending field, with array indices and nested object keys decoded — for example ["amount", "currency"] for a nested field, or ["metadata", "0", "value"] for an array item.

Two special header-validation cases

Two specific missing-header conditions are surfaced with their own error codes instead of a generic invalid_request, because they’re common integration mistakes:
{
  "error": "invalid_idempotency_key",
  "message": "Idempotency-Key header is required."
}
Returned by any write endpoint that requires Idempotency-Key when the header is absent. See Idempotency.
{
  "error": "invalid_organization_context",
  "message": "x-organization-id header is required."
}
Returned when the request’s organization cannot be resolved from the credential or headers. See Authentication → Organization resolution.

Authentication and authorization errors

StatuserrorWhen
401unauthorizedMissing Authorization header, or the bearer token is not a valid API key or Clerk session.
403forbiddenThe credential is valid but the action requires a signed-in dashboard user (not an API key), or the user lacks the required workspace permission.
401 Missing credential
{
  "error": "unauthorized",
  "message": "Missing bearer credential. Provide an API key or session token."
}
403 Signed-in session required
{
  "error": "forbidden",
  "message": "This action requires a signed-in dashboard session."
}
See Authentication for the full set of 401/403 cases.

Not found — 404 not_found

Requesting a resource (by ID) that doesn’t exist for your organization returns 404:
404 Payment intent not found
{
  "error": "not_found",
  "message": "Payment intent pi_xyz was not found for organization org_acme."
}
ReconLayer scopes lookups to your resolved organizationId — a resource that exists in a different organization is indistinguishable from one that doesn’t exist, and both return 404.

Conflicts — 409

409 responses indicate the request was understood but cannot be applied as-is, because of a conflict with existing state. ReconLayer uses several specific codes:
Returned by POST /v1/payment-intents when the externalReference already exists for your organization but the new request’s canonical fields (amounts, currencies, beneficiary, etc.) don’t match the stored payment intent. The response includes the conflicting fields:
{
  "error": "payment_intent_conflict",
  "message": "A payment intent with this external reference already exists for the organization, but the canonical request fields do not match.",
  "caseId": "case_01J...",
  "paymentIntentId": "pi_01J...",
  "externalReference": "invoice-9182",
  "mismatches": [ /* fields that disagree */ ],
  "existing": { "sourceAmount": "100.00", "sourceCurrency": "USD", "...": "..." }
}
See API Design Principles → Business-level uniqueness.
{
  "error": "idempotency_key_conflict",
  "message": "This Idempotency-Key was already used for a different request on this operation."
}
See Idempotency.
{
  "error": "idempotency_request_in_progress",
  "message": "A request with this Idempotency-Key is already being processed."
}
Retry after a short delay. See Idempotency.

Rate limiting — 429

Exceeding your organization’s request rate returns 429 with the standard @fastify/rate-limit error body and RateLimit-* / Retry-After headers. See Rate limits.

Server and upstream errors — 5xx

StatusMeaning
500An unexpected error inside ReconLayer. If this persists, contact support with the request’s timestamp and, if available, the Idempotency-Key used.
502 / 503 / 504Returned when an upstream provider (a bank rail, stablecoin provider, or chain indexer) the request depends on is unavailable or errored. May include upstreamStatus with the upstream’s status code.
A 5xx response means the request may or may not have been applied. For write endpoints, retry with the same Idempotency-Key and the same body — ReconLayer will either replay the completed result or safely re-execute, never duplicate. See Idempotency.

Quick reference

StatuserrorTypical cause
400invalid_requestBody or query failed schema validation; see issues.
400invalid_idempotency_keyMissing Idempotency-Key header on a write endpoint.
400invalid_organization_contextOrganization could not be resolved from credential/headers.
401unauthorizedMissing, invalid, revoked, or expired credential.
403forbiddenAction requires a signed-in dashboard user, or user lacks the required permission.
404not_foundResource does not exist for your organization.
409payment_intent_conflictexternalReference exists with different canonical fields.
409idempotency_key_conflictIdempotency-Key reused with a different request body.
409idempotency_request_in_progressOriginal request with this key is still processing.
429(rate-limit body)Organization exceeded its request rate.
5xxvariesInternal or upstream provider error — safe to retry idempotent writes.

Next steps