Skip to main content

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

CodeMeaningWhen
200 OKSuccessSuccessful GET, PUT, POST
201 CreatedResource createdSuccessful POST that creates a resource
204 No ContentSuccess, no bodySuccessful DELETE
400 Bad RequestInvalid inputValidation errors, malformed JSON
401 UnauthorizedNot authenticatedMissing or expired JWT token
403 ForbiddenNot authorizedValid token but insufficient role, or license invalid
404 Not FoundResource not foundInvalid ID, slug, or basket ID
409 ConflictConflictDuplicate slug, concurrent update
429 Too Many RequestsRate limitedExceeded rate limit
500 Internal Server ErrorServer errorUnexpected 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.