ElebneElebneDocs
Store API

Inventory

Update stock levels for individual products or in bulk. Supports absolute set and relative adjust modes.

Inventory

Update stock levels for individual products or in bulk. The inventory API supports two modes: set (absolute stock level) and adjust (relative delta), with per-variant granularity.

Single stock update

Update the stock quantity for a single product and/or its variants.

PATCH /dev/store/products/{id}/stock

Request body

FieldTypeRequiredDescription
quantityintegerNoNew product-level stock quantity
variantsarrayNoVariant stock updates (see below)

Variant stock object

FieldTypeRequiredDescription
labelstringYesVariant label (case-insensitive match)
quantityintegerYesNew stock quantity for this variant
curl -X PATCH https://api.elebne.ai/api/v1/dev/store/products/THIEB-001/stock \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "quantity": 50,
    "variants": [
      { "label": "Normal", "quantity": 35 },
      { "label": "Grand", "quantity": 15 }
    ]
  }'
const response = await fetch(
  'https://api.elebne.ai/api/v1/dev/store/products/THIEB-001/stock',
  {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer sk_test_YOUR_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      quantity: 50,
      variants: [
        { label: 'Normal', quantity: 35 },
        { label: 'Grand', quantity: 15 },
      ],
    }),
  }
);

const { data } = await response.json();
console.log(data.quantity); // 50
response = requests.patch(
    'https://api.elebne.ai/api/v1/dev/store/products/THIEB-001/stock',
    headers={
        'Authorization': 'Bearer sk_test_YOUR_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'quantity': 50,
        'variants': [
            {'label': 'Normal', 'quantity': 35},
            {'label': 'Grand', 'quantity': 15},
        ],
    },
)

data = response.json()['data']
print(data['quantity']) # 50

Returns the full updated product object.

Bulk inventory update

Update stock for up to 200 products in a single request. Products are matched by externalId (SKU).

PATCH /dev/store/inventory/bulk

ExternalId required

Bulk inventory uses externalId to match products. Make sure your products have externalId set (via create, update, or CSV import).

Request body

FieldTypeRequiredDescription
itemsarrayYesUp to 200 inventory updates

Item object

FieldTypeRequiredDescription
externalIdstringYesProduct SKU / external ID
modestringNoset or adjust. Default: adjust.
quantityintegerNoAbsolute stock level (used when mode: "set")
quantityDeltaintegerNoStock change (used when mode: "adjust"). Positive to add, negative to subtract.
variantsarrayNoPer-variant updates (see below)

Variant bulk object

FieldTypeRequiredDescription
labelstringYesVariant label (case-insensitive)
modestringNoOverrides the item-level mode
quantityintegerNoAbsolute stock (for set mode)
quantityDeltaintegerNoStock delta (for adjust mode)

Set mode vs adjust mode

Set mode (mode: "set") replaces the stock level with an absolute value. Use this when your warehouse system reports current quantities.

Adjust mode (mode: "adjust") applies a delta to the current stock. Stock cannot go below 0. Use this when processing sales or restocks.

curl -X PATCH https://api.elebne.ai/api/v1/dev/store/inventory/bulk \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "externalId": "THIEB-001",
        "mode": "set",
        "quantity": 50,
        "variants": [
          { "label": "Normal", "quantity": 35 },
          { "label": "Grand", "quantity": 15 }
        ]
      },
      {
        "externalId": "YASSA-002",
        "mode": "adjust",
        "quantityDelta": -5
      },
      {
        "externalId": "MAFE-003",
        "mode": "adjust",
        "quantityDelta": 20
      }
    ]
  }'
const response = await fetch(
  'https://api.elebne.ai/api/v1/dev/store/inventory/bulk',
  {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer sk_test_YOUR_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      items: [
        {
          externalId: 'THIEB-001',
          mode: 'set',
          quantity: 50,
          variants: [
            { label: 'Normal', quantity: 35 },
            { label: 'Grand', quantity: 15 },
          ],
        },
        { externalId: 'YASSA-002', mode: 'adjust', quantityDelta: -5 },
        { externalId: 'MAFE-003', mode: 'adjust', quantityDelta: 20 },
      ],
    }),
  }
);

const { data } = await response.json();
console.log(data.updated); // 3
console.log(data.failed);  // 0
response = requests.patch(
    'https://api.elebne.ai/api/v1/dev/store/inventory/bulk',
    headers={
        'Authorization': 'Bearer sk_test_YOUR_KEY',
        'Content-Type': 'application/json',
    },
    json={
        'items': [
            {
                'externalId': 'THIEB-001',
                'mode': 'set',
                'quantity': 50,
                'variants': [
                    {'label': 'Normal', 'quantity': 35},
                    {'label': 'Grand', 'quantity': 15},
                ],
            },
            {'externalId': 'YASSA-002', 'mode': 'adjust', 'quantityDelta': -5},
            {'externalId': 'MAFE-003', 'mode': 'adjust', 'quantityDelta': 20},
        ],
    },
)

data = response.json()['data']
print(f"Updated: {data['updated']}, Failed: {data['failed']}")

Response

{
  "success": true,
  "data": {
    "updated": 3,
    "failed": 0,
    "errors": []
  }
}

When some items fail, the response includes per-item errors while the successful items are still applied:

{
  "success": true,
  "data": {
    "updated": 2,
    "failed": 1,
    "errors": [
      { "externalId": "UNKNOWN-SKU", "error": "Product not found" }
    ]
  }
}

List inventory

Get a compact inventory view of all tracked products (those with quantity set).

GET /dev/store/inventory?lowStock=true&page=1&limit=100
ParameterTypeDefaultDescription
lowStockstring--Set to true to only show items below the low-stock threshold
pageinteger1Page number
limitinteger100Results per page (max 100)
curl "https://api.elebne.ai/api/v1/dev/store/inventory?lowStock=true" \
  -H "Authorization: Bearer pk_test_YOUR_KEY"
const response = await fetch(
  'https://api.elebne.ai/api/v1/dev/store/inventory?lowStock=true',
  {
    headers: { 'Authorization': 'Bearer pk_test_YOUR_KEY' },
  }
);

const { items, total, hasMore } = await response.json();
for (const item of items) {
  if (item.isLowStock) {
    console.log(`Low stock: ${item.name} (${item.quantity} left)`);
  }
}
response = requests.get(
    'https://api.elebne.ai/api/v1/dev/store/inventory',
    headers={'Authorization': 'Bearer pk_test_YOUR_KEY'},
    params={'lowStock': 'true'},
)

result = response.json()
for item in result['items']:
    if item['isLowStock']:
        print(f"Low stock: {item['name']} ({item['quantity']} left)")

Response

{
  "success": true,
  "data": {
    "items": [
      {
        "productId": "6612f1a2b3c4d5e6f7890123",
        "externalId": "THIEB-001",
        "name": "Thiéboudienne Royale",
        "quantity": 3,
        "lowStockThreshold": 5,
        "isLowStock": true,
        "variants": [
          { "variantId": "6612f...", "label": "Normal", "quantity": 2 },
          { "variantId": "6612f...", "label": "Grand", "quantity": 1 }
        ]
      }
    ],
    "total": 1,
    "page": 1,
    "hasMore": false
  }
}

Error responses

Error codeHTTPDescription
VARIANT_NOT_FOUND400Variant label does not match any variant on the product
VARIANT_LABEL_AMBIGUOUS400Multiple variants share the same label
TOO_MANY_ITEMS400Bulk request exceeds 200 items
PRODUCT_NOT_FOUND404Product not found by ID or externalId

Next steps

  • Products -- create products with variants before updating stock
  • CSV Import -- bulk import products with initial quantities
  • Webhook Events -- get notified on product.stock_low and product.stock_out

Was this page helpful?

On this page