Skip to main content
The Caratuva API returns errors with a consistent envelope:
{
  "statusCode": 400,
  "error": "KybNotApproved",
  "message": "Your organization has no virtual account. Complete KYB first.",
  "requestId": "b1f2c3d4-5e6a-4b7c-8d9e-0f1a2b3c4d5e"
}
Every error carries statusCode, message, and requestId. Every error code documented below also carries a machine-readable error.
FieldPurpose
statusCodeMirrors the HTTP status.
errorStable, machine-readable code. Switch on this. Present on every documented error code (some framework-level 404s omit it).
messageHuman-readable explanation. A string for most errors; an array of path: reason strings for ValidationError. Don’t switch on this — wording may change.
requestIdA UUID that correlates to our logs, also returned in the x-request-id response header. Include it in support requests.

HTTP status mapping

StatusWhen
400Validation failed, business rule violated, or precondition not met.
401Missing, malformed, expired, or revoked credential.
403Authenticated, but the credential lacks the required scope or role.
404Resource doesn’t exist or isn’t visible to your organization.
409Conflict — most often IdempotencyKeyConflict or a race on a unique field.
429Rate-limit exceeded.
500Unexpected server error. Safe to retry with the same Idempotency-Key.
503Platform maintenance or an upstream rail outage. Check status.caratuva.com. May be returned by the edge without the standard JSON envelope.

Common error codes

The list below covers the codes you’re most likely to encounter while integrating.

Auth

CodeStatusCause
AuthenticationRequired401No credential presented. Send X-API-Key (or, for the dashboard, Authorization: Bearer).
InvalidApiKeyFormat401Header isn’t pk_(test|live)_<id>.<secret>.
InvalidApiKey401Key is unknown, revoked, or doesn’t match the stored hash.
JwtExpired401Bearer JWT past its exp. Re-authenticate via the dashboard.
InvalidJwt401Bearer JWT malformed, bad signature, or missing claims.
InsufficientScope403API key lacks the scope required for this endpoint.

Validation

CodeStatusCause
ValidationError400Request body failed schema validation. message is an array of path: reason strings.
IdempotencyKeyConflict409The Idempotency-Key was already used for a different resource. Use a fresh key.

Lifecycle

CodeStatusCause
KybNotApproved400Your organization hasn’t cleared KYB. Live operations are gated; test mode still works.
ProductionAccessNotApproved400Live mode isn’t enabled yet. Submit a Production Access Request and wait for Caratuva approval.
AmountBelowMinimum400The USD amount is below the US$10.00 bank-transfer funding minimum, so the buyer couldn’t pay it. Increase the amount.
PixPayoutKeyMissing400No PIX payout key registered. Configure payouts in the dashboard first.
InvalidInvoiceState400Tried to edit or reassign an invoice past its editable state (draft / awaiting_approval).
InvalidTransition400Illegal state transition — e.g. cancelling an invoice or payment intent that’s already past the cancellable point.
A missing or invalid buyer email surfaces as ValidationError, not a dedicated code. Re-POSTing the same externalId returns the existing intent rather than an error (see Payment intents).

Rate limiting

CodeStatusCause
RateLimitExceeded429You exceeded the per-API-key limit. The JSON body includes retryAfter (seconds) — wait that long, then retry.

Server

CodeStatusCause
InternalServerError500Unexpected server-side failure. Safe to retry with the same idempotency key.

Retry guidance

StatusRetry?How
4xx (except 429)NoThe request will fail the same way again. Fix the input.
429YesWait retryAfter seconds (from the response body), then retry. Don’t hammer.
500, 502, 503, 504YesWith exponential backoff, reusing the same Idempotency-Key so a retry can’t create a duplicate resource.
Network error / timeoutYesSame as 5xx. The original may or may not have committed; reusing the idempotency key keeps it safe.

What to log

When an API call fails, log:
  • requestId — lets us find your exact request in our logs (also on the x-request-id response header).
  • error — the stable machine code.
  • The endpoint and the request body with secrets redacted (never log the API key secret half or Idempotency-Key headers if they encode user data).
A good support escalation includes the requestId and the error code. With those two we can usually answer in minutes.