Error Codes Reference

Every API error returns a machine-readable code and a human-readable message.

All error responses follow this shape:
{ "success": false, "error": { "code": "ERROR_CODE", "message": "...", "details": {} } }
CodeHTTPDescription & When It Occurs
AUTH_REQUIRED401No Authorization header or token missing.
INVALID_TOKEN401JWT is expired, malformed, or user no longer exists.
INVALID_CREDENTIALS401Wrong email/password combination.
INVALID_OTP401Submitted TOTP code is incorrect.
FORBIDDEN403Authenticated but lacks permission for this resource.
INSUFFICIENT_PERMISSION403Role does not have the required permission key.
TENANT_SUSPENDED403Tenant account has been suspended by platform.
NOT_FOUND404Requested resource does not exist.
TENANT_NOT_FOUND404X-Tenant-ID header refers to non-existent tenant.
LICENCE_EXPIRED402Tenant licence has expired.
PAYMENT_FAILED402Payment initiation or webhook processing failed.
USER_EXISTS409Email is already registered in this tenant.
VALIDATION_ERROR422Request body is missing required fields or has invalid values.
STOCK_INSUFFICIENT422One or more variants have insufficient stock.
COUPON_INVALID422Coupon is inactive, not yet started, usage limit reached, or below min order.
COUPON_EXPIRED422Coupon's expires_at is in the past.
OTP_NOT_SETUP400Tried to verify OTP before calling /otp/setup.
RATE_LIMIT_EXCEEDED429Too many requests from this IP in the time window.
INTERNAL_ERROR500Unhandled server-side error. Check server logs.