Concepts
Errors
The error format, the types and the codes.
Monerails uses HTTP status codes: 2xx means it worked, 4xx that the request cannot succeed as sent, 5xx that something went wrong on our side or at a partner. Errors always have the same shape:
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "amount must be an integer between 1 and 100000000000 (minor units)",
"param": "amount",
"request_id": "req_3aec3e6d1222495eb183"
}
}| Field | Description |
|---|---|
type |
Family of the error (table below). |
code |
Precise reason, stable: branch your code on it. |
message |
Explanation for a developer. It can change: do not parse it. English by default, French with Accept-Language: fr. |
param |
The parameter at fault, when there is one. |
object_id, card |
The object created before the failure, when there is one (for example a card the issuer refused). |
request_id |
Give it to support. |
Messages never contain internal or partner details. A request that fails for a reason without its own code returns 400 request_invalid with the message “The request could not be processed. Check the parameters.” 5xx errors always have a generic message. Refusals by an operator or the card issuer keep their reason, under 402 provider_declined.
Status codes
| Status | Meaning |
|---|---|
200 |
OK. |
201 |
Created. |
202 |
Accepted: the operation was sent and its outcome is not final yet. Follow it with webhooks. |
400 |
Invalid request. |
401 |
Missing or invalid key. |
402 |
Valid request that could not be carried out. |
403 |
Not allowed. |
404 |
Unknown object or endpoint. |
409 |
Conflict, for example another operation in progress. |
422 |
Idempotency key reused with other parameters. |
429 |
Too many requests. |
5xx |
Our side or a partner. Retry with the same Idempotency-Key. |
Types
| Type | HTTP | Description |
|---|---|---|
invalid_request_error | 400, 404, 405, 409, 413 | The request is wrong: missing or invalid parameter, unknown object or endpoint. |
authentication_error | 401 | No API key, or an invalid, revoked or orphaned key. |
permission_error | 403 | The key’s creator does not have the role required, the business is suspended, or live mode is not open yet. |
request_failed | 402 | Valid request that could not be carried out: insufficient balance, refusal by the operator or the issuer, wrong code. |
idempotency_error | 409, 422 | The Idempotency-Key is still in use or was used with other parameters. |
rate_limit_error | 429 | Too many requests. Wait for Retry-After seconds. See Rate limits. |
api_error | 500, 502, 503 | A problem on our side or at a partner. The message is always generic. Retry with the same Idempotency-Key. |
Codes
| Code | HTTP | Description |
|---|---|---|
api_key_invalid | 401 | Missing, malformed, unknown or revoked key. |
api_key_owner_removed | 401 | The member who created the key left the business. Create a new key. |
account_suspended | 403 | The business account is suspended. |
permission_denied | 403 | The key’s creator does not have the role required for this operation. |
live_mode_unavailable | 403 | Live mode opens once your business verification is approved. |
parameter_missing | 400 | A required parameter is missing. See param. |
parameter_invalid | 400 | A parameter has the wrong type or value. See param. |
parameter_unknown | 400 | The body contains a parameter the endpoint does not accept. |
body_invalid | 400 | The body is not a JSON object. |
body_too_large | 413 | The body is larger than 12 MB. |
resource_missing | 404 | No object with this ID in this mode. |
route_unknown | 404 | Unknown endpoint. |
method_not_allowed | 405 | The endpoint exists but not with this HTTP method. |
idempotency_key_invalid | 400 | The key is longer than 255 characters. |
idempotency_key_in_use | 409 | A request with this key is still running. |
idempotency_key_reused | 422 | This key was already used with different parameters. |
currency_unsupported | 400 | This currency is not open. |
country_unsupported | 400 | This country is not open for this currency. See Coverage. |
bank_transfer_unsupported | 400 | Bank payouts are not available in this country: pay to a mobile money wallet. |
test_phone_required | 400 | Test mode: use one of the test phone numbers of this country. See Testing. |
otp_not_expected | 400 | This collection is not waiting for a code (already authorized, or no code needed). |
amount_invalid | 400 | Amount out of range, for example a card funding above $100,000, or a CDF amount that is not whole francs. |
amount_too_small | 400, 402 | Amount below the minimum (for cards: issuing fee plus $1). |
amount_too_large | 402 | Amount above the maximum allowed by the operator. |
operator_unsupported | 400, 402 | Unknown operator, or refused by the payment partner for this currency. |
phone_invalid | 400 | The number cannot be read as an international number. |
bank_account_invalid | 400 | bank_code does not exactly match a code from List banks, or the account number is too short. |
balance_insufficient | 402 | Your balance (or cards balance) does not cover the amount and the fee. |
recipient_invalid | 402 | The payment partner rejected the recipient. |
otp_invalid | 400, 402 | Wrong, malformed or expired code. |
provider_declined | 402 | The operator or the card issuer declined. message gives their reason. |
settlement_destination_missing | 400 | No settlement account saved for this currency. |
settlement_destination_invalid | 400 | The saved settlement account is not valid for the payment partner. |
cardholder_exists | 409 | A cardholder already uses this email. |
cardholder_not_verified | 400 | The cardholder’s identity is not verified yet. |
id_document_unsupported | 400 | Unsupported identity document type. |
document_invalid | 400 | A document image is not accepted: JPEG or PNG only, 4 MB at most, at least 600 × 400 px. param names the side. |
cardholder_underage | 400 | The cardholder must be at least 18 years old. |
identity_already_registered | 402 | The card issuer already holds this identity for a pending or completed verification. Contact support. |
verification_declined | 402 | The card issuer declined the verification submission. Check the details and document images, then submit again. |
agent_cards_not_enabled | 400 | Agent cards are not set up yet. An Owner must issue the first agent card from the dashboard. |
card_not_ready | 400 | The card is not issued yet. |
card_terminated | 400 | The card is terminated. |
card_already_frozen | 400 | The card is already frozen. |
card_not_frozen | 400 | The card is not frozen. |
card_minimum_balance | 400 | At least $1 must stay on the card. |
card_single_use | 400 | Single-use cards cannot be funded or withdrawn from. |
card_operation_in_progress | 409 | Another operation is running on this card. Retry in a few seconds. |
url_invalid | 400 | Not an HTTPS URL with a domain name, or it contains user:password@. IP addresses are refused. |
events_invalid | 400 | An event pattern is malformed. |
limit_reached | 400 | A limit is reached: 10 webhook endpoints per business (test and live together), or 500 beneficiaries per mode. |
beneficiary_exists | 409 | A beneficiary with this number or account already exists in this mode. |
request_invalid | 400 | Other invalid request. The message is generic: “The request could not be processed. Check the parameters.” |
verification_not_submitted | 400 | The test helper needs a verification submitted first. |
test_mode_only | 400 | Test helpers need a test key. |
test_limit_reached | 400 | A card test mode limit was reached (test cards balance, test top-up, active test cards; 429 for the monthly issuance quota). See Testing. |
rate_limited | 429 | A rate limit was reached. Wait for Retry-After seconds. See Rate limits. |
provider_unavailable | 503 | This service is not open in this mode yet. |
provider_insufficient_funds | 503 | The payment partner cannot process this payout right now. Retry later. |
provider_error | 502 | A partner could not be reached. Retry with the same Idempotency-Key. |
upload_failed | 500 | Document upload failed. Retry. |
internal | 500 | Unexpected error. Retry; contact support with the request_id if it persists. |
Rate limits
Requests beyond a limit fail with 429 rate_limited and a Retry-After header. The limits are on Rate limits.