Error Codes
This page lists all possible error codes returned by the EquipDash API.
Error Response Formatโ
All errors follow this structure:
{
"error": {
"code": "error_code",
"message": "Human-readable error message",
"details": { ... } // Optional additional context
},
"meta": {
"request_id": "req_abc123"
}
}
Authentication Errors (4xx)โ
| Code | HTTP Status | Description |
|---|---|---|
authentication_required | 401 | No API key was provided in the request |
invalid_api_key | 401 | The API key is invalid or malformed |
api_key_expired | 401 | The API key has passed its expiration date |
api_key_revoked | 401 | The API key has been revoked |
ip_not_allowed | 403 | Request IP is not in the API key's whitelist |
test_key_readonly | 403 | Test API key used for a write operation |
account_suspended | 403 | The account this key belongs to has been suspended by EquipDash. Contact EquipDash support |
insufficient_scope | 403 | API key lacks the required scope for this operation |
Resource Errors (4xx)โ
| Code | HTTP Status | Description |
|---|---|---|
resource_not_found | 404 | The requested resource does not exist |
forbidden | 403 | You don't have permission to access this resource |
conflict | 409 | The request conflicts with current state (e.g., double booking) |
module_disabled | 403 | The supplier has the relevant module (rentals / experiences / store) disabled โ see Supplier Modules |
module_disabled exampleโ
Endpoints that touch a specific module (products, workshop, bundles,
experiences, experience-categories, store products, store categories) return
this error when the supplier has the corresponding module turned off in their
EquipDash settings. The response includes the offending module so clients
can decide what to do (refresh their cached module flags, hide the feature,
prompt the supplier admin to re-enable it).
{
"error": {
"code": "module_disabled",
"message": "Experiences module is not enabled for this supplier.",
"module": "experiences"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-04-15T03:14:15Z"
}
}
Call GET /supplier/modules (no scope required) to learn which modules are
enabled for the authenticated supplier and adjust your UI accordingly.
Validation Errors (422)โ
When request data is invalid:
{
"error": {
"code": "validation_error",
"message": "The given data was invalid.",
"details": [
{ "field": "email", "message": "The email field is required." },
{ "field": "start_date", "message": "The start date must be after today." }
]
},
"meta": {
"request_id": "req_abc123"
}
}
Rate Limiting Errors (429)โ
| Code | HTTP Status | Description |
|---|---|---|
rate_limit_exceeded | 429 | Too many requests in the time window |
The response includes a Retry-After header and retry_after in details:
{
"error": {
"code": "rate_limit_exceeded",
"message": "You have exceeded the rate limit.",
"details": {
"retry_after": 45
}
}
}
Server Errors (5xx)โ
| Code | HTTP Status | Description |
|---|---|---|
internal_error | 500 | An unexpected error occurred |
service_unavailable | 503 | The service is temporarily unavailable |
Handling Errorsโ
Check HTTP Status Firstโ
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 401:
// Handle authentication errors
console.error('Authentication failed:', error.error.message);
break;
case 403:
// Handle authorization errors
console.error('Access denied:', error.error.message);
break;
case 404:
// Handle not found
console.error('Resource not found');
break;
case 422:
// Handle validation errors
error.error.details.forEach(d => {
console.error(`${d.field}: ${d.message}`);
});
break;
case 429:
// Handle rate limiting
const retryAfter = error.error.details.retry_after;
console.log(`Rate limited. Retry after ${retryAfter}s`);
break;
default:
console.error('API error:', error.error.message);
}
}
Use the Request ID for Supportโ
Every response includes a unique request_id in the meta object. Include this when contacting support:
{
"meta": {
"request_id": "req_abc123def456"
}
}
The request ID is also returned in the X-Request-Id response header.