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": {} } }| Code | HTTP | Description & When It Occurs |
|---|---|---|
| AUTH_REQUIRED | 401 | No Authorization header or token missing. |
| INVALID_TOKEN | 401 | JWT is expired, malformed, or user no longer exists. |
| INVALID_CREDENTIALS | 401 | Wrong email/password combination. |
| INVALID_OTP | 401 | Submitted TOTP code is incorrect. |
| FORBIDDEN | 403 | Authenticated but lacks permission for this resource. |
| INSUFFICIENT_PERMISSION | 403 | Role does not have the required permission key. |
| TENANT_SUSPENDED | 403 | Tenant account has been suspended by platform. |
| NOT_FOUND | 404 | Requested resource does not exist. |
| TENANT_NOT_FOUND | 404 | X-Tenant-ID header refers to non-existent tenant. |
| LICENCE_EXPIRED | 402 | Tenant licence has expired. |
| PAYMENT_FAILED | 402 | Payment initiation or webhook processing failed. |
| USER_EXISTS | 409 | Email is already registered in this tenant. |
| VALIDATION_ERROR | 422 | Request body is missing required fields or has invalid values. |
| STOCK_INSUFFICIENT | 422 | One or more variants have insufficient stock. |
| COUPON_INVALID | 422 | Coupon is inactive, not yet started, usage limit reached, or below min order. |
| COUPON_EXPIRED | 422 | Coupon's expires_at is in the past. |
| OTP_NOT_SETUP | 400 | Tried to verify OTP before calling /otp/setup. |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests from this IP in the time window. |
| INTERNAL_ERROR | 500 | Unhandled server-side error. Check server logs. |