Developer Docs

← Back to Console

Inventory API

The Inventory API enables you to query product catalog data and real-time stock levels for your business. Use it to check availability before creating orders or to sync stock data with external systems.

Overview

Authentication

Both inventory endpoints require:

See the Authentication guide for how to obtain a JWT token with the inventory:read scope.

List Inventory

Retrieve a list of all active inventory items for your business.

Request

GET /e9v3/inventory?search=<query>&limit=100
Authorization: Bearer <jwt-token>

Query Parameters

Parameter Type Required Default Max Description
search string No — — Filter by SKU, product name, category, or barcode (case-insensitive)
limit integer No 100 500 Maximum number of results to return per page
cursor string No — — Previous page’s nextCursor. Omit for the first page — existing clients that only send search/limit are unchanged.

Response (200 OK)

{
  "success": true,
  "inventory": [
    {
      "itemId": "inv_a1b2c3d4",
      "businessId": "biz-456",
      "sku": "WIDGET-001",
      "productName": "Premium Widget",
      "description": "High-quality widget for industrial use",
      "category": "Widgets",
      "brand": "Acme",
      "barcode": "9781234567890",
      "imageUrl": "https://storage.example.com/widget-001.jpg",
      "availableQuantity": 150,
      "totalQuantity": 200,
      "reservedQuantity": 30,
      "orderedQuantity": 20,
      "returnsQuantity": 0,
      "unitOfMeasure": "pcs",
      "isActive": true,
      "isComposite": false,
      "stockStatus": "inStock"
    }
  ],
  "count": 1,
  "hasMore": false
}

Response Fields

Field Type Description
itemId string Unique inventory item identifier
businessId string Business this item belongs to
sku string Stock Keeping Unit code
productName string Product display name
description string Product description
category string Product category
brand string Brand name (if set)
barcode string Barcode / GTIN (if set)
imageUrl string Product image URL (if set)
availableQuantity integer Quantity available for new orders
totalQuantity integer Total stock on hand
reservedQuantity integer Quantity reserved for pending orders
orderedQuantity integer Quantity on outstanding purchase orders
returnsQuantity integer Quantity pending return processing
unitOfMeasure string Unit of measure (e.g., pcs, kg, m)
isActive boolean Whether the item is active (inactive items are excluded from listings)
isComposite boolean Whether the item is a composite/kit product
stockStatus string Computed status: inStock, lowStock, critical, outOfStock
metadata object Free-form custom attributes

List-level paging fields (additive — existing clients that ignore unknown JSON keys are unchanged):

Field Type Description
count integer Number of items in this page
hasMore boolean true when another page is available
nextCursor string Pass as cursor on the next request. Omitted when hasMore is false

Paging: limit is a page size (max 500), not a cap on the catalog. Existing GET /e9v3/inventory?limit=100 (or ?search=&limit=) calls still return the first page with success, inventory, and count. To dump the whole catalog, loop while hasMore is true and pass nextCursor as cursor.

Data source: list and search both read the versioned InventoryIndex (quantities as of the last IndexRegenerate). Variant SKUs appear as extra rows with itemId of the parent product. Get-by-id reads the live Inventory document. Inactive items (isActive: false) are silently excluded from the list endpoint. If no index is published, list returns 404 with "Inventory index not published".

Stock Status Logic

Status Condition
inStock Available > 25% of total
lowStock Available between 10%–25% of total
critical Available below 10% of total
outOfStock Available is 0 or total is 0

Get Single Item

Look up a specific inventory item by its ID. This reads the live Inventory document (not the versioned index).

Request

GET /e9v3/inventory/:itemId
Authorization: Bearer <jwt-token>

Response (200 OK)

{
  "success": true,
  "inventory": [
    {
      "itemId": "inv_a1b2c3d4",
      "sku": "WIDGET-001",
      "productName": "Premium Widget",
      "availableQuantity": 150,
      "totalQuantity": 200,
      "stockStatus": "inStock"
    }
  ],
  "count": 1
}

Response (404 Not Found)

{
  "success": false,
  "error": "Inventory item not found"
}

Declare On-Hand Quantity

Set (not adjust) the absolute on-hand quantity for a SKU. This is applied through the platform’s transactional inventory pipeline as an asynchronous job and returns a jobId — poll GET /e9v3/jobs/:jobId for the outcome. Requires the inventory:write scope.

Request

POST /e9v3/inventory/sync
Authorization: Bearer <jwt-token>
Content-Type: application/json
{
  "sku": "WIDGET-001",
  "quantity": 200,
  "sourceRecordId": "stocktake-2024-01-15"
}

Response (200 OK)

{
  "success": true,
  "jobId": "inventory_1776400267719207348"
}

Notes:

See the Endpoints reference for the full schema.

Upsert and Archive Catalog Items

Create, update or archive catalog items by SKU, for example to keep a storefront’s product list in step. These routes change item metadata only: stock quantities are never changed. Requires the inventory:write scope.

Route What it does
POST /e9v3/inventory/items Creates or updates one item keyed by sku. Returns { success, itemId, action } where action is created or updated.
POST /e9v3/inventory/items/batch Up to 50 items in { items: [...] }, with a per-item result in results (partial success is allowed). More than 50 items returns 400.
POST /e9v3/inventory/items/{sku}/archive Archives the item (moved to the archive, never hard-deleted). Idempotent when already archived.

Request

POST /e9v3/inventory/items
Authorization: Bearer <jwt-token>
Content-Type: application/json
{
  "sku": "WIDGET-001",
  "name": "Widget",
  "barcode": "9300000000001",
  "weightGrams": 250,
  "active": true,
  "sourceRecordId": "shopify:my-shop:variant:42"
}

Notes:

Common Use Cases

Check stock before creating an order

# 1. Search for the product by SKU
curl -X GET 'https://api.equos.one/e9v3/inventory?search=WIDGET-001' \
  -H 'Authorization: Bearer <jwt-token>'

# 2. Verify availableQuantity >= order quantity
# 3. Create the order if stock is sufficient
curl -X POST 'https://api.equos.one/e9v3/orders/send' \
  -H 'Authorization: Bearer <jwt-token>' \
  -H 'Content-Type: application/json' \
  -d '{"customerId": "cust-123", "items": [{"sku": "WIDGET-001", "productName": "Premium Widget", "quantity": 5}]}'

Sync stock levels to an external system

# First page (same call existing integrations already make)
curl -X GET 'https://api.equos.one/e9v3/inventory?limit=500' \
  -H 'Authorization: Bearer <jwt-token>'

# Following pages: repeat until hasMore is false
curl -X GET 'https://api.equos.one/e9v3/inventory?limit=500&cursor=<nextCursor>' \
  -H 'Authorization: Bearer <jwt-token>'

Filter by category

curl -X GET 'https://api.equos.one/e9v3/inventory?search=Electronics&limit=50' \
  -H 'Authorization: Bearer <jwt-token>'

Error Handling

Status Meaning
200 Success
401 Invalid or missing Bearer token
403 Token lacks inventory:read scope
404 Item not found (single item lookup), or inventory index not published (list/search)
429 Rate limit exceeded
500 Server error

Next Steps