REST API / Errors
REST API / Errors
Error handling
All errors use a consistent JSON envelope with a machine-readable code, a human-readable message, and the HTTP status. Validation errors include a
details array with per-field messages.Error shape
Standard error
{
"error": {
"code": "NOT_FOUND",
"message": "Product not found in your catalogue",
"status": 404
}
}Validation error
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"status": 400,
"details": [
{
"field": "ship_name",
"message": "required"
},
{
"field": "items[0].quantity",
"message": "must be at least 1"
}
]
}
}Error codes
MISSING_API_KEY401No x-api-key header was sent.INVALID_API_KEY401Key format is wrong or does not exist.KEY_REVOKED403Key has been manually revoked.KEY_EXPIRED403Key has passed its expiry date.ACCOUNT_INACTIVE403Reseller account is pending, suspended, or rejected.INSUFFICIENT_SCOPE403Key is valid but does not carry the access right this endpoint needs. Enable it under Access rights on the API keys page.RATE_LIMIT_EXCEEDED429More than 60 requests in one minute.VALIDATION_ERROR400Request body or query parameters failed validation.PAYMENT_REQUIRED402No payment card is on file. Add one under Settings → Payment before placing orders. Only POST /v1/orders returns this.NOT_FOUND404Resource does not exist or is not in your catalogue.CONFLICT409Action conflicts with current resource state.FORBIDDEN403You do not have permission.INTERNAL_ERROR500An unexpected server error occurred.INTERNAL_ERROR503Rate limiting is temporarily unavailable, so the request was refused rather than served unmetered. Retryable — a Retry-After header says when.Handling errors in code
JavaScript
const res = await fetch("https://api.feedapi.co.uk/v1/products", {
headers: { "x-api-key": apiKey },
});
if (!res.ok) {
const { error } = await res.json();
switch (error.code) {
case "RATE_LIMIT_EXCEEDED":
const retryAfter = res.headers.get("Retry-After");
await sleep(Number(retryAfter) * 1000);
break;
case "INVALID_API_KEY":
case "KEY_REVOKED":
// Redirect to key management
break;
case "VALIDATION_ERROR":
error.details?.forEach(d => showFieldError(d.field, d.message));
break;
default:
console.error(error.message);
}
}