Error codes
Complete reference of all API error codes, HTTP statuses, and resolution steps.
Overview
When an API request fails, JoPay returns a JSON response with an error field containing a machine-readable error code. This page lists every error code, its HTTP status, what it means, and how to fix it.
{
"error": "invalid_amount",
"message": "Amount must be a positive number"
}
Rate limiting
| Code | HTTP | Meaning | How to fix |
|---|
rate_limited | 429 | Too many requests in the current window. | Wait for the rate limit window to reset. Check the rate limits reference for per-endpoint limits. |
Authentication
| Code | HTTP | Meaning | How to fix |
|---|
unauthorized | 401 | No valid session or API key provided. | Log in again or provide a valid API key in the request header. |
auth_failed | 401 | Authentication credentials are invalid. | Verify your API key or session token. Re-authenticate if the session has expired. |
invalid_id_token | 401 | The provided identity token is malformed or expired. | Request a fresh ID token from your authentication provider and retry. |
missing_id_token | 401 | No identity token was provided in the request. | Include the ID token in the authorization header of your request. |
Validation
| Code | HTTP | Meaning | How to fix |
|---|
invalid_amount | 400 | The payment amount is missing, negative, zero, or not a valid number. | Provide a positive numeric amount. For zero-decimal currencies (JPY, KRW, CLP), the amount must be a whole number. |
invalid_currency | 400 | The specified currency code is not in the list of 28 supported currencies. | Use a valid ISO 4217 currency code from the supported currencies list. |
invalid_frequency | 400 | The recurring billing frequency is not one of the allowed values. | Use one of: daily, weekly, or monthly. |
invalid_customer_wallet | 400 | The customer wallet address is not a valid Ethereum-format address. | Provide a valid 0x-prefixed, 42-character hexadecimal address. |
invalid_withdraw_address | 400 | The withdrawal address is malformed or invalid. | Provide a valid 0x-prefixed Ethereum address for the withdrawal destination. |
invalid_email | 400 | The email address is malformed. | Provide a valid email address in standard format (user@domain.com). |
invalid_body | 400 | The request body is missing or not valid JSON. | Send a well-formed JSON body with the correct Content-Type header (application/json). |
invalid_request | 400 | The request is malformed or missing required fields. | Review the API documentation for the endpoint and include all required fields. |
Wallet
| Code | HTTP | Meaning | How to fix |
|---|
recurring_requires_embedded_wallet | 400 | Recurring billing is a v1 feature that runs via a customer-signed ERC-7715 grant to the public recurring-pull executor. This error is returned when a caller tries to create a recurring plan before the caveat-enforcer suite is audited and deployed on-chain. | Not actionable by partners. Recurring plans become available once the caveat-enforcer suite clears audit and deploys. See Recurring plans. |
auto_forward_requires_embedded_wallet | 400 | Auto-forward is a v1 feature that runs via a user-signed ERC-7715 grant to the public auto-forward executor. This error is returned when a caller tries to enable auto-forward before the caveat-enforcer suite is audited and deployed on-chain. | Not actionable by partners. Auto-forward becomes available once the caveat-enforcer suite clears audit and deploys. See Auto-forward. |
Payment
| Code | HTTP | Meaning | How to fix |
|---|
unsupported_currency | 400 | The requested currency is recognized but not enabled for this partner. | Contact your partner to enable the currency, or use a different supported currency. |
amount_exceeds_max | 400 | The payment amount exceeds the maximum allowed per transaction. | Reduce the payment amount. The maximum is configured at the partner level. |
Webhook
| Code | HTTP | Meaning | How to fix |
|---|
webhook_not_configured | 400 | The partner has not configured a webhook URL. | Set a webhook URL in the partner admin portal before enabling webhook-dependent features. |
invalid_webhook_url | 400 | The provided webhook URL is not a valid HTTPS URL. | Provide a fully qualified HTTPS URL (e.g., https://example.com/webhooks/jopay). HTTP URLs are not accepted. |
System
| Code | HTTP | Meaning | How to fix |
|---|
api_error | 500 | An unexpected internal error occurred. | Retry the request after a short delay. If the error persists, contact support with the request ID. |
rpc_error | 500 | A blockchain RPC call failed. | This is usually transient. Retry after a few seconds. If persistent, the RPC provider may be experiencing an outage. |
rpc_unavailable | 503 | The blockchain RPC endpoint is unreachable. | The RPC provider is temporarily unavailable. Retry with exponential backoff. On-chain operations will resume when the provider recovers. |
fx_unavailable | 503 | FX rate data is temporarily unavailable. | The FX rate provider is down. Cached rates may be used as a fallback. Retry after a few minutes. |
Recurring
| Code | HTTP | Meaning | How to fix |
|---|
plan_not_found | 404 | The specified recurring plan ID does not exist or does not belong to this merchant. | Verify the plan ID. Ensure it belongs to the current merchant and partner. |
plan_already_terminated | 400 | The recurring plan has already been cancelled and cannot be modified. | Create a new recurring plan if the customer wants to restart billing. |
can_only_pause_active_plans | 400 | Only plans with status active can be paused. | Check the plan status before attempting to pause. Only active plans can be paused. |
can_only_resume_paused_plans | 400 | Only plans with status paused can be resumed. | Check the plan status before attempting to resume. Only paused plans can be resumed. |
✅When handling errors programmatically, always match on the error code string, not the HTTP status code. Multiple error types can share the same HTTP status.