Inventory API
Fenicia's Inventory API manages your products' stock by location: querying and updating stock levels, transferring stock between locations, manual adjustments, and cycle/physical counts.
Read this entire page before integrating
This API has behaviors that differ between resources (pagination format, field names, error codes). These are not cosmetic inconsistencies — they directly affect how you must parse responses. They are documented explicitly below.
What can you do?
- Query the stock of a SKU in a location, or the full listing with filters.
- Update the stock of a SKU in a location (
PUT) or in bulk (bulk-update). - Transfer stock between locations (creation, approval, and receiving).
- Adjust stock manually with an auditable reason (shrinkage, damage, count correction, etc.).
- Run counts, cyclic or physical, and apply the resulting variance as an adjustment.
Base URL
https://api.fenicia.ioAll endpoints in this domain live under /inventory/*. The related Locations domain (/locations/*) manages the locations and zones that each inventory record's locationId points to, but it is not part of this reference.
Data model
An inventory record (Inventory) represents the stock of one SKU in one location. The compound key {tenantId, sku, locationId} is unique: there is exactly one document per SKU/location combination.
{
"tenantId": "69db07c8bce4d49b18c42a49",
"sku": "CAM-ROJO-M",
"productSku": "CAM-ROJO",
"locationId": "loc_abc123",
"stock": 42,
"compromised": 0,
"handler": null,
"handlerType": "manual",
"createdAt": "2026-01-10T12:00:00.000Z",
"updatedAt": "2026-06-01T09:15:00.000Z"
}| Field | Type | Description |
|---|---|---|
sku | string | Variant SKU. |
productSku | string | Parent product SKU (optional). |
locationId | string | Location this record belongs to. |
stock | number | Current stock on hand. |
compromised | number | Reserved/committed stock. See the warning below. |
handler | string | null | Identifier of the integration/channel controlling this record, if applicable. |
handlerType | manual | integration | channel | Origin of stock control. |
There is no 'available stock' endpoint in this domain
The compromised field (reserved/committed stock) exists in the schema, but no Inventory API endpoint reads, writes, or calculates it. There is no endpoint that returns available = stock − compromised. That calculation is resolved by the Products and Orders domains in their own views — if your integration needs "available vs. committed", you won't find it here.
Response format
This API does not use a single {data, meta} envelope. Each resource returns the shape its own endpoint defines, and those shapes are not consistent with one another:
| Resource | List response shape |
|---|---|
/inventory, /inventory/location/:id | { items: Inventory[], pagination: { page, limit, total, pages } } |
/inventory/transfers | { transfers: InventoryTransfer[], pagination } |
/inventory/adjustments | { adjustments: InventoryAdjustment[], pagination } |
/inventory/counts | { counts: InventoryCount[], pagination } |
Detail endpoints (GET .../:id) return the raw document, unwrapped (for example, GET /inventory/transfers/:id returns the InventoryTransfer object directly, not { transfer: {...} }).
Pagination — important warning
Pagination does NOT use the same index across all endpoints
Endpoints under /inventory (stock listing, transfers, adjustments, counts) are 1-indexed: page defaults to 1. If you integrate a single pagination helper reused across your whole client, always check the default page value for the specific endpoint you're calling — using the same helper without adjusting produces a silent off-by-one.
| Endpoint | Default page |
|---|---|
GET /inventory | 1 |
GET /inventory/location/:id | 1 |
GET /inventory/transfers | 1 |
GET /inventory/adjustments | 1 |
GET /inventory/counts | 1 |
Authentication
All requests require the Authorization header with your API key:
Authorization: Bearer fkapi_your_api_keySee Authentication for the full key creation and rotation process.
Tip
Each endpoint documents the exact permission (scope) it requires, for example inventory:read or inventory:update. An API key without that scope receives 403.
Quick start
curl 'https://api.fenicia.io/inventory?limit=10' \
-H 'Authorization: Bearer fkapi_your_api_key'Related articles
- Query and update stock — read and write stock by SKU/location.
- Transfers — move stock between locations.
- Adjustments — correct stock with an auditable reason.
- Counts — cyclic and physical counts.