Every failed minipim API request returns the same JSON shape, with an HTTP status that matches the problem. Read error.code in code; error.message is for people.
With the API
{
"error": {
"code": "validation_failed",
"message": "body failed validation",
"details": {
"issues": [
{ "path": ["name"], "message": "Required", "code": "invalid_type" }
]
}
}
}
That is the response to a POST /v1/products with no name. details is optional. For validation failures it carries issues, each with a path (where the problem is), a message and a code.
| Status | error.code | When |
|---|---|---|
401 | unauthenticated | Missing, malformed, revoked or expired credentials |
403 | forbidden | Authenticated, but the action is not allowed (for example, a disabled optional feature, or no membership in the requested organization) |
404 | not_found | The entity does not exist or belongs to another organization |
409 | conflict | A uniqueness clash, such as a duplicate product slug, modifier code or brand name, or a modifier already attached to the product |
422 | validation_failed | The body, path or query failed validation, or a business rule rejected the write |
500 | internal | An unhandled server error. The message is always internal server error |
Other 4xx errors raised by the web framework itself, such as a malformed JSON body or an upload over the size limit, use the same envelope with the framework’s own code (for example FST_ERR_…).
With the TypeScript SDK, use isMinipimError(error) to narrow the value and getErrorMessage(error, fallback) to pull the message out:
import { getErrorMessage } from '@minipim/sdk';
const { data, error } = await pim.GET('/v1/products/{id}', { params: { path: { id } } });
if (error) throw new Error(getErrorMessage(error, 'product lookup failed'));
Rules and limits
- A
404never confirms that an id exists in another organization. Tenancy is enforced in the database, so other organizations’ rows are simply invisible. - Unknown query parameters on
GET /v1/productsandGET /v1/categoriesare a422naming the unrecognized key. See Listing, filtering and pagination. - Attribute values are validated against the product’s family. An attribute code the family does not declare, or a value of the wrong shape, is a
422. See Attribute types. - Setting a product to
activewithout its family’s required attributes is a422. See Product status. - Bulk endpoints such as
POST /v1/products/bulkanswer200with aresultsarray. Each item is{ "ok": true, "index", "id" }or{ "ok": false, "index", "error" }, so check every item rather than the status code. See Bulk editing. - Some successful writes return a
warningsarray instead of failing, for example a media upload that completed with something worth knowing. Log warnings; don’t treat them as errors. - A revoked key can keep authenticating for up to about 60 seconds after revocation, so a
401may lag slightly. See API keys. - Retry
5xxresponses and network failures with backoff. A4xxwill not succeed on retry until you change the request.
The API reference lists the error statuses each endpoint can return.
See also
- REST API basics — Base URL, authentication, JSON conventions, IDs, money and dates for the minipim /v1 REST API, plus where to find the live OpenAPI reference.
- Listing, filtering and pagination — How minipim list endpoints page with limit, offset and hasMore, which ones return plain arrays, and the filters, sorts and limits /v1/products accepts.
- API keys — Issue, rename and revoke minipim API keys. Keys start with pim_, are shown once, carry their own organization, and authenticate every /v1 request.
- TypeScript SDK — Use @minipim/sdk: a typed client generated from the OpenAPI spec, pagination helpers, attribute and money helpers, and webhook signature verification.