Locations live at https://api.fenicia.io/locations/* — a different base path and service from /inventory/*. They have their own permission namespace (locations:*), their own pagination convention, and their own response shape. Don't assume the rules documented for /inventory/* apply here.
A Location (Location) is a warehouse, physical store, a marketplace fulfillment center (FBA, Mercado Full), or any other point where stock is kept or managed. A Place is a zone within a location — a shelf, a receiving zone, a damaged-goods zone — which can in turn be broken down into placements (aisle, island, endcap, bin, rack, etc.), the exact physical position within that zone.
shopify-fullfillment (with a double "ll") is the literal enum value in production — it is not a typo in this documentation. Do not "fix" it to shopify-fulfillment in your integration; the exact value is the one you see here.
id, code, type (enum, see below), name, description?, active (default true),maxCapacity?, pickPriority?, availableForSale?,placements?: [{ code, type (enum, see below), label? }]
GET /locations paginates 0-indexed with a default limit of 10 (not 20). Its response is { locations, totalCount, page, limit } — note totalCount, not total as in the rest of the inventory domain.
This endpoint returns 400 (not 404) with code: "bad-request/not-found" when the service cannot resolve the count. It's an unusual code/status combination — documented as it behaves today, not "fixed".
Gets a location by ID or by locationCode (unified lookup). Requires locations:read.
idstringrequired
MongoDB ID or locationCode — both resolve through the same path param.
200
{ "location": { "id": "loc_cedis_cdmx", "name": "CEDIS Ciudad de México", "type": "warehouse" } }
404
{ "code": "not-found", "message": "Location not found" }
The only endpoint in this domain that uses code:'not-found' on a 404
Within lambda-locations, onlyGET /locations/{id} uses the literal code not-found on a 404. Every other 404 in this domain (see the table below) uses bad-request/not-found — a bad-request/-prefixed code on a 404 status. Documented literally, this is not a typo in this guide.
capabilities is not validated against the catalog on create or update — only type is checked against its enum. A capabilities value that doesn't exist in the catalog is silently accepted. (Code observation: not confirmed with an independent negative test; it is the absence of a catalog check for capabilities in the controller, analogous to the one that does exist for type.)
{ "code": "bad-request/system-location", "message": "Cannot remove default flag from a system location" }
Two-step write, no transaction
Internally, marking a location as default first clears isDefault on all other locations of the tenant (updateMany) and then marks the target location — these are two separate writes, without a Mongo session/transaction wrapping them. In theory, a failure between the two steps could leave the tenant with no default location at all. This is an observation about the shape of the code, not a confirmed production incident.
{ "code": "bad-request/system-location", "message": "Cannot delete a system location" }
No referential integrity check
Deleting a location does not check whether Inventory records still reference it as locationId. It is possible to leave orphaned inventory records pointing at a deleted location.
The zone's id is generated by the server (UUID). Uniqueness of code within a location is checked in memory at creation time, not via a database unique index.