Developer documentationGet API keys

Errors

Every failure has the same shape, whatever went wrong.

{
  "error": {
    "type": "card_error",
    "code": "card_declined",
    "message": "Insufficient funds.",
    "decline_code": "insufficient_funds",
    "doc_url": "https://ronda.sh/docs/errors#card_declined"
  }
}

type tells you how to react; code is the stable machine-readable identifier; message is safe to show a human. param appears when a specific field was at fault. Internal detail — bank payloads, SQL, stack traces — never crosses this boundary.

Error types

TypeStatusWhat it means
invalid_request_error400 / 404Something about the request was wrong: a missing parameter, a bad value, an unknown object.
authentication_error401The API key was missing, malformed, unknown or revoked.
permission_error403Authenticated, but not allowed: a missing scope, a blocked IP, or a suspended account.
card_error402The bank declined. Look at decline_code.
rate_limit_error429Too many requests. Retry-After tells you when.
idempotency_error409An Idempotency-Key was re-used with a different body, or is still in flight.
api_error500Something failed on our side. Retry; the payment intent is already recorded.

Decline codes

Normalised across banks, so your handling does not change when Ronda adds a second bank.

CodeWhat to do
card_declinedThe issuer refused without a specific reason. Ask the customer to try another card.
insufficient_fundsNot enough money on the card. The most common real decline — worth retrying later, which is what dunning does.
expired_cardThe card has expired. Only the customer can fix this; send them a portal link.
incorrect_cvcThe security code did not match.
authentication_required3-D Secure was required and not completed.
binding_inactiveThe saved card is no longer valid at the bank. Ask the customer to add a card again.
limit_exceededThe amount is above the card's limit.
processing_errorThe bank could not process the card. Safe to retry.

Retrying safely

A 500 or a network timeout does not mean the payment failed — it means you do not know. Retry the request with the same Idempotency-Key: if the first attempt succeeded you get the original payment back, and if it did not, the charge happens exactly once. Never retry with a fresh key.

Rate limits

300 requests per minute per API key, and 120 per minute per IP on the unauthenticated surfaces. A 429 carries a Retry-After header in seconds. Card-testing velocity limits apply separately to checkout attempts: 10 per IP and 6 per customer in a ten-minute window.