Error Handling

The Partner API uses standard HTTP status codes and returns consistent JSON error responses.

Error Response Format

Most errors follow this structure:

json
{
	"statusCode": 400,
	"message": "Validation failed",
	"error": "Bad Request"
}

Status Codes

CodeErrorDescription
400Bad RequestInvalid request body, unknown fields, validation failure, or daily order limit
401UnauthorizedMissing or invalid API key; missing signing headers on a signed endpoint
403ForbiddenSignature 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)
404Not FoundThe requested resource does not exist, or a savedCardId does not belong to your organization
409ConflictA request with the same idempotency key is currently in flight
422Unprocessable EntityInsufficient wallet balance for a wallet payment
429Too Many RequestsRate limit exceeded (includes a retryAfter field)
500Internal Server ErrorAn unexpected error occurred on the server

Validation Errors

Request bodies are validated strictly. For 400 errors, the message field lists which fields failed:

json
{
	"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:

json
{
	"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):

json
{
	"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:

json
{
	"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:

json
{
	"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 statusCode field to determine the error category.
  • For 403 errors 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 409 errors 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 422 wallet errors, top up your wallet balance and retry.
  • For 500 errors, retry with exponential backoff and an idempotency key. If the error persists, contact support.