Skip to content

Reference · 149 codes

Errors

Every failed request answers with the same body. Switch on code; the message is for people and can change.

Error body
{
  "code": "idempotency_conflict",
  "message": "This Idempotency-Key was already used for a different request.",
  "request_id": "0192f1e0-4c2a-7f8e-9a1b-3c4d5e6f7a8b",
  "retryable": false
}
FieldMeaning
codeA stable, machine-readable string. New codes can appear in any 1.x version, so always keep a default branch.
messageA sentence safe to show to a person. Do not parse it.
request_idThe same value as the X-Request-ID response header. Quote it when you contact support.
retryableTrue when the same request may succeed later without a change. The SDKs retry these for you.

Handling errors

  • Branch on code, then on retryable for the codes you do not know.
  • Retry a retryable error with the same Idempotency-Key, after the Retry-After delay when there is one, with exponential backoff and a limit on attempts.
  • Never retry a non-retryable error unchanged. Fix the request or tell the person.
  • Log request_id with every failure.

curl

# No amount and no price: 400 amount_required.
curl -sS -i "$RAVELO_API/v1/payment-intents" \
  -H "Authorization: Bearer $RAVELO_TEST_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "order_ref": "order-1", "asset_id": "usdt-tron" }'

TypeScript

import { Ravelo, RaveloError } from "@ravelo/sdk";

const ravelo = new Ravelo({ apiKey: process.env.RAVELO_TEST_KEY!, baseUrl: process.env.RAVELO_API! });

try {
  await ravelo.paymentIntents.create({ order_ref: "order-1", asset_id: "usdt-tron" }); // neither amount nor price
} catch (err) {
  if (!(err instanceof RaveloError)) throw err;
  switch (err.code) {
    case "amount_required":
      console.log("send amount or price");
      break;
    case "address_pool_empty":
    case "operation_paused":
      console.log("try again shortly"); // both are retryable; err.retryable says so
      break;
    default:
      // The API may add codes without a new version. Log the request id: support can find the call with it.
      console.error(err.status, err.code, err.message, err.requestId);
  }
}

Python

import os

from ravelo import ErrorCode, Ravelo, RaveloError

ravelo = Ravelo(os.environ["RAVELO_TEST_KEY"], os.environ["RAVELO_API"])

try:
    ravelo.payment_intents.create(order_ref="order-1", asset_id="usdt-tron")  # neither amount nor price
except RaveloError as err:
    if err.code == ErrorCode.AMOUNT_REQUIRED:
        print("send amount or price")
    elif err.retryable:
        print("try again shortly")
    else:
        # The API may add codes without a new version. Log the request id: support can find the call with it.
        print(err.status, err.code, err.message, err.request_id)

HTTP statuses

StatusMeaning
400The request is malformed or a field is invalid. Fix the request; repeating it unchanged fails again.
401No valid API key. Check the Authorization header and that the key is not revoked or expired.
403The key is valid but not allowed: a missing scope (insufficient_scope), a live key on a test-only call, or a frozen account.
404No such resource in this account. Test and live objects are separate accounts.
409The request conflicts with the current state, or an Idempotency-Key was reused with a different body.
422The request is well formed but a business rule refused it: below the minimum, over a limit, an address still cooling off.
423Money out is paused for a while after a security change on the account.
429Rate limit reached. Wait Retry-After seconds.
5xxSomething failed on our side or a dependency is unavailable. Retry with the same Idempotency-Key.

All codes

This table is generated from the API's error catalogue when the site is built. Codes used only by the staff console are not listed.

149 of 149 codes

CodeHTTPRetryableMeaning
above_ceiling422noA fee above its operation's hard ceiling is blocked.
account_changed409noThe session now works in a different account than the client believes; reload and retry.
account_inactive403noThe account is frozen, suspended or closed, so the action is refused.
address_cooling_off422noA saved address cannot receive payouts until its 24-hour cooling-off ends.
address_exists409noThe address is already in the address book.
address_not_found422noThe address is not in this account's address book.
address_pool_empty503yesNo deposit address is free right now; retry shortly.
already_fulfilled409noThe payment is already fulfilled.
already_handled409noThe payout approval was already approved or rejected.
already_invited409noThis address already has a pending invitation to the account; resend it from the team page.
already_member409noThis address already belongs to an active member of the account.
amount_and_price400noBoth amount and price were given; send one.
amount_required400noNeither amount nor price was given.
approval_expired409noThe payout or refund waited too long for approval and was cancelled; its funds are back in the available balance.
approver_must_differ403noA different team member must approve a payout or refund the caller prepared.
asset_id_required400noasset_id is required.
below_minimum422noThe amount is below the minimum for this asset and operation.
body_too_large400noThe request body exceeds the size limit.
callback_invalid400noThe provider callback body could not be parsed.
ceremony_invalid400noThe passkey ceremony is invalid or expired; start again.
conversion_unavailable409noConversion is not available right now; nothing was quoted or converted.
country_already_set409noPUT /v1/me/country only fills a missing country; one is already on record (declared at sign-up or confirmed by staff) and only staff correct it.
country_required403noThe merchant has not given a country yet, so payment intents and checkout sessions are refused until they do (PUT /v1/me/country, or staff confirm it during verification). Payouts, refunds and returns are not affected. Read GET /v1/capabilities, eligibility.country_required.
csrf_invalid403noThe CSRF token is missing or invalid. Session requests only; API keys are not affected.
deletion_owner_blocked409noYou are the only owner of an open account; hand ownership over or close the account before asking for deletion.
deletion_request_exists409noA deletion request is already waiting for review.
deposits_disabled422noPayments are disabled for this asset.
email_taken409noAnother user already signs in with this email.
email_unverified403noThe email address must be verified before signing in.
empty_patch400noThe update contained no fields to change.
endpoint_disabled409noThe webhook endpoint must be enabled first.
fee_exceeds_amount422noThe fee would exceed the amount; increase the amount.
forbidden403noThe caller's role does not allow this action.
idempotency_conflict409noThe Idempotency-Key was already used for a different request.
idempotency_key_required400noPOST requests require an Idempotency-Key header of 1-255 characters.
insufficient_available_balance422noThe available balance does not cover the amount plus fees.
insufficient_scope403noThe API key lacks the scope this endpoint needs.
integration_paused403noRavelo staff paused this API key, connected app or account integration.
intent_not_payable409noThe payment intent is not awaiting payment or has no active instructions.
internal_error500yesAn unexpected server error; retry with the same Idempotency-Key.
invalid_address422noThe address is not valid for the network.
invalid_amount400noThe amount is not a positive integer in base units.
invalid_asset400noasset_id is missing or invalid.
invalid_country400nocountry is missing, is not an ISO 3166-1 alpha-2 code, or subdivision is not an ISO 3166-2 code inside it. Sign-up requires a country.
invalid_credentials401noThe email, password or code is incorrect.
invalid_currency400noThe currency is not a supported ISO 4217 code.
invalid_cursor400noThe pagination cursor is not valid for this list or sort.
invalid_email400noThe email address is not valid.
invalid_event_type400noThe webhook event type is unknown.
invalid_expiry400noThe expiry is outside the allowed range.
invalid_from400nofrom is not an RFC 3339 timestamp.
invalid_json400noThe request body is not valid JSON for this endpoint.
invalid_kind400noThe kind filter holds an unknown value.
invalid_label400noThe label must be 1-64 characters.
invalid_limit400nolimit is outside its allowed range.
invalid_locale400noThe locale is not a BCP-47 language tag.
invalid_max_amount400nomax_amount is not a non-negative integer in base units.
invalid_metadata400nometadata must be a JSON object under 4 KB.
invalid_min_amount400nomin_amount is not a non-negative integer in base units.
invalid_mode400noThe key mode must be live or test.
invalid_month400noThe month must be YYYY-MM.
invalid_name400noThe name must be 1-64 characters.
invalid_offset400nooffset is not a whole number of zero or more.
invalid_operation400noThe operation is not one the endpoint accepts.
invalid_order400noorder must be asc or desc.
invalid_origin400noThe origin must be a normalized https origin, or http localhost in test mode, without a path, query or fragment.
invalid_overlap400nooverlap_seconds is outside 0 to 604800.
invalid_period400noThe period is malformed or too long.
invalid_price400noprice needs a currency and a positive amount_minor.
invalid_range400noThe range value is not one the endpoint accepts.
invalid_role400noThe role is not valid for this action.
invalid_schedule422noThe fee schedule is invalid.
invalid_scope400noscopes must be a non-empty list of known scopes.
invalid_status400noThe status filter holds an unknown value.
invalid_text400noA text field holds a control character such as NUL, or a formatting character an identifier does not accept.
invalid_time_zone400noThe time zone is not an IANA name.
invalid_to400noto is not an RFC 3339 timestamp or date.
invalid_url400noThe URL must be a public https endpoint without credentials.
invalid_username400noUsernames are 3-24 lowercase letters, digits or underscores.
invitation_wrong_user403noThe signed-in person is not the one the invitation was sent to; the message names the masked address. The link is not spent: sign in as the invited person.
key_inactive409noThe API key is revoked or expired.
last_owner409noAn account keeps at least one owner.
legal_version_stale409noThe legal text is no longer current; accept the current version.
login_exists409noThe invited address already has a login, so it cannot create one; sign in and accept the invitation.
lookalike_address422noThe address resembles a saved one but differs; check every character.
market_not_eligible403noThe merchant's registered market does not allow this activity: new payments are refused in a restricted market, while payouts, refunds and returns of the merchant's own funds go to staff review instead. Sign-up from a blocked market answers the same. Read GET /v1/capabilities for what the market allows.
method_not_allowed405noThe HTTP method is not allowed on this path.
mfa_required403noA second factor is needed; set up MFA and confirm with a code. Sign-in also answers 401 when the code is missing.
network_mismatch422noThe address belongs to another network than the asset.
no_asset_price422noThe asset has no price to convert from; send amount instead.
no_fee_rule422noNo fee rule applies to this operation right now.
not_acceptable409noOnly a short payment with nothing verifying or held can be accepted.
not_cancellable409noOnly a payment nobody has paid yet can be cancelled.
not_found404noThe resource does not exist in this account.
not_implemented501noThe endpoint is not implemented.
not_succeeded409noOnly a succeeded payment can be fulfilled.
open_intents_cap_reached429yesThis account already has the maximum number of open payment intents; let some be paid, expire or be cancelled, then retry.
operation_disabled422noThe operation is not available for this asset.
operation_outcome_unknown409noThe provider's outcome for this operation is not proven. Do not retry; the funds stay reserved until staff resolve it, then the status changes.
operation_paused503yesThe platform paused this operation; retry later.
order_ref_required400noorder_ref is required.
origin_exists409noThis origin is already approved for the account.
origin_not_approved403noThe origin is not in this account's approved checkout origins.
other_browser403noThe connection must be approved in the browser that started it.
over_daily_limit422noThe amount exceeds the remaining daily limit.
over_monthly_limit422noThe amount exceeds the remaining monthly limit.
over_per_transaction_limit422noThe amount exceeds the per-transaction limit.
overpay_nothing_held422noThe payment holds no overpayment to return.
overpay_return_in_progress409noA return of this overpayment is already under way.
overpay_window_closed409noThe window to return the overpayment has closed; staff return it.
passkey_failed422noThe passkey could not be verified.
passkey_unknown401noThe passkey is not registered.
password_breached400noThe password appears in a known data breach.
policy_restricted403noA policy restriction applies to this account, asset or network, so the action is refused. Contact support; retrying does not help.
price_unavailable503yesNo current price is available, so the operation is paused for the asset.
quote_changed409noFees changed since the quote; get a new quote and confirm again.
quote_expired409noA conversion quote expired before it was used; request a new one.
rate_limited429yesToo many requests; wait for Retry-After seconds.
reason_required400noA reason of at most 500 characters is required.
refund_destination_unverified422noRefund to the payer's address or save the address first.
refund_exceeds_entitlement422noThe refund exceeds what the payer is entitled to.
refund_exceeds_received422noRefunds would exceed what the payment received.
schedule_not_pending409noThe fee schedule is not awaiting approval.
scope_not_allowed403noThe role cannot grant an app one of the requested permissions.
security_freeze423noPayouts are paused for 48 hours after a security change.
session_required403noThe endpoint needs a signed-in team member, not an API key or app.
signature_invalid401noThe callback signature is missing or invalid.
step_up_failed422noThe confirmation code is not valid.
test_mode_only403noThe endpoint is only available to test-mode API keys.
test_mode_unavailable503noThis deployment has no sandbox simulator, so test-mode requests are refused.
token_expired422noThe link or invitation has expired.
token_invalid422noThe link is invalid or was already used.
too_long400noA field exceeds its length limit.
too_many_endpoints409noDisable an endpoint before adding another (10 active at most).
too_many_keys409noRevoke an unused key before creating another.
too_many_origins409noRemove an unused checkout origin before adding another (50 at most).
totp_enabled409noAn authenticator app is already enabled.
totp_not_enrolled409noStart enrolment before confirming.
travel_rule_invalid400notravel_rule is incomplete.
travel_rule_required422noTransfers of this value need the beneficiary's details.
unauthenticated401noNo valid credential was sent.
unknown_asset400noasset_id is not a listed asset.
unknown_currency400noNo rate is available for the currency.
unknown_network400noThe network is not one of the supported networks.
unknown_symbol400noNo asset has this symbol.
username_taken409noThe username is taken.
weak_password400noPasswords must be 10-128 characters.
widget_token_expired401noThe short-lived checkout widget token has expired; request a fresh token from the merchant backend.
withdrawals_disabled422noPayouts are disabled for this asset.