Error Handling
The Quark Commerce API uses standard HTTP status codes and returns consistent JSON error responses.
Error Response Format
{
"message": "Human-readable error description"
}
For validation errors (400):
{
"errors": {
"Email": ["The Email field is required."],
"Password": ["Password must be at least 8 characters."]
}
}
Status Codes
| Code | Meaning | When |
|---|---|---|
200 OK | Success | Successful GET, PUT, POST |
201 Created | Resource created | Successful POST that creates a resource |
204 No Content | Success, no body | Successful DELETE |
400 Bad Request | Invalid input | Validation errors, malformed JSON |
401 Unauthorized | Not authenticated | Missing or expired JWT token |
403 Forbidden | Not authorized | Valid token but insufficient role, or license invalid |
404 Not Found | Resource not found | Invalid ID, slug, or basket ID |
409 Conflict | Conflict | Duplicate slug, concurrent update |
429 Too Many Requests | Rate limited | Exceeded rate limit |
500 Internal Server Error | Server error | Unexpected errors |
Rate Limiting
When rate limited, the response includes a Retry-After header:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json
{
"status": 429,
"message": "Rate limit exceeded. Please retry after 60 seconds.",
"retryAfter": 60
}
Three rate limit policies exist:
- Fixed — 100 requests/minute (global)
- Search — 60 requests/minute (search endpoints)
- Sliding — 20 requests/10 seconds (burst protection)
Handling Errors in Your App
// Example: HTTP error handling (framework-agnostic)
if (error.status === 401) {
// Token expired — attempt refresh
return this.authService.refreshToken().pipe(
switchMap(() => next.handle(req))
);
}
if (error.status === 429) {
// Rate limited — wait and retry
const retryAfter = error.headers.get('Retry-After') || 60;
return timer(retryAfter * 1000).pipe(
switchMap(() => next.handle(req))
);
}
if (error.status === 403) {
// Check if it's a license issue vs permission issue
// License issues affect ALL endpoints
}
tip
Always check for message in the response body for user-friendly error descriptions. The API consistently provides descriptive messages.