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.

Statuserror.codeWhen
401unauthenticatedMissing, malformed, revoked or expired credentials
403forbiddenAuthenticated, but the action is not allowed (for example, a disabled optional feature, or no membership in the requested organization)
404not_foundThe entity does not exist or belongs to another organization
409conflictA uniqueness clash, such as a duplicate product slug, modifier code or brand name, or a modifier already attached to the product
422validation_failedThe body, path or query failed validation, or a business rule rejected the write
500internalAn 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 404 never 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/products and GET /v1/categories are a 422 naming 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 active without its family’s required attributes is a 422. See Product status.
  • Bulk endpoints such as POST /v1/products/bulk answer 200 with a results array. 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 warnings array 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 401 may lag slightly. See API keys.
  • Retry 5xx responses and network failures with backoff. A 4xx will 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.