Skip to content

Errors

The Kreezalid APIs report errors in two ways, and a robust client handles both:

  1. Request errors: the request could not be served (no credentials, unknown resource, wrong method). They come with a 4xx code.
  2. Refused operations: the request was understood, but the write was refused (a required field is missing, a category does not exist). Most write endpoints report these with "success": false in the body, often with a 200 status.
Code Meaning What to do
200 Success, or a refused write. Read success on write endpoints.
201 Created. Some creation endpoints use it, others answer 200. Treat 200 and 201 alike.
400 Invalid parameters. Fix the request.
403 Missing or wrong credentials, or the resource is not yours. Check authentication and the base URL.
404 The resource or the endpoint does not exist, or the page is past the last one. Check the id, the path and the page.
405 The endpoint exists but not with this HTTP method. Use the method shown in the reference.
406 The body could not be used, for instance a metafield without value. Fix the body.
422 Validation failed (Front API). Show the message to the user.
301 You called another address of the marketplace. Call the primary address, see Base URLs.
503 The marketplace is in maintenance. Retry after the Retry-After delay.
5xx A server error. Retry with backoff; report it if it persists.

Errors are returned as JSON with the HTTP code repeated in code:

{
"message": "Listing with ID 999999 cannot be found",
"url": "/api/v1/listings/999999",
"code": 404
}
{
"message": "Permission denied, wrong credentials",
"url": "/api/v1/orders",
"code": 403
}

A path that matches no endpoint at all also carries the method:

{
"message": "Not Found",
"url": "/api/v1/listings/645646/photos",
"method": "GET",
"code": 404
}

Create, update and delete endpoints answer with success and a human-readable message:

{
"id": null,
"message": "Field price is required",
"success": false
}
{
"success": false,
"message": "Error. No updates were made."
}

When a user cannot be created because of invalid fields, message is an object keyed by field, then by rule:

{
"id": null,
"success": false,
"message": { "address_zipcode": { "maxLength": "The postal code must be at most 20 characters long" } },
"content": []
}

Validation messages follow the marketplace’s language, so match on the field and rule names, not on the text.

POST /api/v1/checkout/preauth-success is the exception: it answers 400 with an errors list naming each invalid field:

{
"code": 400,
"status": "error",
"message": "Invalid request params",
"errors": [
{ "field": "tos_acceptance_at", "message": "tos_acceptance_at is not a valid date (YYYY-MM-DD HH:MM:SS)" }
]
}

Refused writes and unknown paths are answered in JSON, like the Admin API. Authentication failures (403) and resources that do not exist or do not belong to the vendor (404) come back with the right status code but an HTML error page as the body. Check the status code before parsing the body.

The Front API answers in JSON for the errors it anticipates, with a body that depends on the endpoint family:

Endpoints Error body
Authentication, account {"code": 403, "status": "error", "message": "Token not found in request"}
Cart items {"success": false, "error": "This product is no longer available for purchase."}
Cart creation, shipping method {"status": "failed", "message": "There is no such order in this cart"}
Wishlists {"success": false, "message": "listing_already_in_user_wishlist"}

A listing or an order that does not exist, a request made while already signed in to an endpoint for visitors, or a path that matches no endpoint, returns the right 4xx status with an HTML page as the body.

Whatever the API, the same few lines cover every case:

kreezalid.mjs
export async function call(url, init) {
const res = await fetch(url, { ...init, redirect: 'manual' });
const isJson = (res.headers.get('content-type') || '').includes('application/json');
const body = isJson ? await res.json() : await res.text();
const code = (isJson && typeof body.code === 'number') ? body.code : res.status;
if (code >= 300 || (isJson && body.success === false)) {
const message = isJson ? (body.message ?? body.error ?? JSON.stringify(body)) : `HTTP ${res.status}`;
const err = new Error(typeof message === 'string' ? message : JSON.stringify(message));
err.status = code;
err.retryable = code === 429 || code >= 500;
throw err;
}
return body;
}