Error Handling
The Partner API uses standard HTTP status codes and returns consistent JSON error responses.
Error Response Format
Most errors follow this structure:
{
"statusCode": 400,
"message": "Validation failed",
"error": "Bad Request"
}Status Codes
| Code | Error | Description |
|---|---|---|
400 | Bad Request | Invalid request body, unknown fields, validation failure, or daily order limit |
401 | Unauthorized | Missing or invalid API key; missing signing headers on a signed endpoint |
403 | Forbidden | Signature mismatch, expired timestamp, reused nonce, IP/endpoint not allowed, or organization not active (generic message Authentication failed); or a product/country restriction (PRODUCT_NOT_AVAILABLE, COUNTRY_NOT_AVAILABLE) |
404 | Not Found | The requested resource does not exist, or a savedCardId does not belong to your organization |
409 | Conflict | A request with the same idempotency key is currently in flight |
422 | Unprocessable Entity | Insufficient wallet balance for a wallet payment |
429 | Too Many Requests | Rate limit exceeded (includes a retryAfter field) |
500 | Internal Server Error | An unexpected error occurred on the server |
Validation Errors
Request bodies are validated strictly. For 400 errors, the message field lists which fields failed:
{
"statusCode": 400,
"message": [
"payment.method must be one of the following values: saved_card, wallet",
"products.0.productId must be a string"
],
"error": "Bad Request"
}Unknown Fields Are Rejected
The API rejects any field not defined in the request schema (strict whitelisting). Sending an unknown or removed field fails the whole request:
{
"statusCode": 400,
"message": ["property paymentMethodId should not exist"],
"error": "Bad Request"
}Remove any fields not documented in the current reference before sending.
Insufficient Wallet Balance (422)
When a wallet payment cannot be covered by your prepaid balance, the API returns a 422 with a machine-readable code and balance details in EUR minor units (cents):
{
"statusCode": 422,
"code": "INSUFFICIENT_WALLET_BALANCE",
"message": "Insufficient wallet balance: have 1250, need 4990 (minor units).",
"balanceMinor": "1250",
"requiredMinor": "4990"
}See the Wallet section for funding details.
Product Availability (403)
Product availability can vary per partner. When a product family (vignettes, eSIM, insurance) is not enabled for your organization, listings and order creation return a 403 with a machine-readable code:
{
"statusCode": 403,
"code": "PRODUCT_NOT_AVAILABLE",
"message": "Product 'vignetteToll' is not available for this organization"
}Individual countries may also be restricted. Restricted-country items are omitted from listings, and ordering them (or querying eSIM packages with a restricted country) returns:
{
"statusCode": 403,
"code": "COUNTRY_NOT_AVAILABLE",
"message": "Country 'RU' is not available for product 'esim' for this organization"
}These restrictions apply in both live and test environments and are checked before your idempotency key is claimed, so a rejected request can be retried unchanged once the restriction is lifted. Contact your account manager if you believe a product or country should be available.
Best Practices
- Always check the
statusCodefield to determine the error category. - For
403errors on signed requests, the message is intentionally generic. Verify your signing key derivation (SHA-256 of the secret), timestamp freshness (within 5 minutes), nonce uniqueness, and body serialization. See Authentication. - For
409errors on order creation, an identical request is still processing. Wait briefly and retry with the same idempotency key; once the original completes you will receive its cached result. - For
422wallet errors, top up your wallet balance and retry. - For
500errors, retry with exponential backoff and an idempotency key. If the error persists, contact support.