Inventories API (GraphQL)
This guide is for third party integrations that read Stylux inventory over GraphQL. It covers the inventories query, including nested products and stop sales policies.
For request signing (headers, canonical string, working example), see Signed API Authentication.
Endpoint
Send a POST to /graphql.
| Environment | URL |
|---|---|
| Production | https://api.stylux.io/graphql |
| Staging | https://api-stg.stylux.io/graphql |
| Development | https://api-dev.stylux.io/graphql |
Use Content-Type: application/json and Accept: application/json.
Authentication
Requests use HMAC signed API keys. Follow Signed API Authentication for every request.
Your signed API key must include at least:
read:inventoriesfor inventory and policy fieldsread:productsfor nestedproductfields
GraphQL: inventories
An inventory is a shared quantity pool at a location. One or more products can point at the same inventory through inventory products. Quantity, sales status, and stop sales policy live on the inventory, not on each product. If two SKUs share a pool, they share availableQuantity and salesStatus.
Inventory (quantity pool)
products[] (InventoryProduct; one per grouped product)
product (Product)
inventoryPolicies[] (InventoryPolicy)
Paginated fields use Relay style connections: nodes, edges { cursor node }, and pageInfo { hasNextPage hasPreviousPage startCursor endCursor }.
Every paginated field requires first or last (max 250). Forward paging: first plus optional after. Backward paging: last plus before. Nested products and inventoryPolicies need their own first/last; they do not inherit the parent page size. With a STOP_SALES_POLICY filter, at most one policy is returned, so inventoryPolicies(first: 1) is enough.
Default sort is createdDate descending (internally tied to insertion order). You can pass sort: { columns: ["availableQuantity"], operator: DESC } on inventories. Allowed sort columns: createdDate, updatedDate, availableQuantity, allocatedQuantity.
Recommended query
query InventoriesPage(
$first: Int!
$after: String
$filter: GetManyInventoriesFilter
) {
inventories(first: $first, after: $after, filter: $filter) {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
nodes {
id
createdDate
updatedDate
inventoryId
availableQuantity
allocatedQuantity
inventoryLevelStatus
salesStatus
products(first: 50) {
nodes {
id
position
product {
id
sku
productId
title
}
}
}
inventoryPolicies(
first: 1
filter: { inventoryPolicyType: STOP_SALES_POLICY }
) {
nodes {
id
config {
type
minInventory
}
}
}
}
}
}Variables example:
{
"first": 50,
"after": null,
"filter": null
}Walk pages while pageInfo.hasNextPage is true: pass pageInfo.endCursor as after on the next request. Sign each request separately (new nonce, new timestamp, new signature over the new body).
Fetch one inventory by id:
query InventoryById($id: UUID!) {
inventory(id: $id) {
id
availableQuantity
salesStatus
products(first: 50) {
nodes {
product {
id
sku
title
}
}
}
inventoryPolicies(
first: 1
filter: { inventoryPolicyType: STOP_SALES_POLICY }
) {
nodes {
config {
type
minInventory
}
}
}
}
}Inventory fields
| Field | Notes |
|---|---|
id | Stylux inventory UUID |
inventoryId | Optional external / merchant inventory identifier |
availableQuantity | Units available to sell |
allocatedQuantity | Units already allocated |
inventoryLevelStatus | NONE, LOW, or SUFFICIENT |
salesStatus | LIVE or STOPPED |
createdDate / updatedDate | ISO 8601 timestamps |
products | Paginated grouped products (see below) |
inventoryPolicies | Paginated policies (filter to stop sales as shown) |
Inventory product and product
Inventory.products returns InventoryProduct nodes (the grouping links), not Product directly. Each node is one product in the pool. Walk every node to see the full group; do not assume a single product per inventory.
position is the order of products within that group.
| InventoryProduct field | Notes |
|---|---|
id | Link row UUID |
position | Order within the inventory group |
product | The catalog product in this group |
For integrations, product.id, product.sku, product.productId, and product.title are usually enough. product.id is the Stylux UUID. product.productId is the external product identifier (for Shopify, this is the variant id).
Filtering inventories by productId / productIds uses Stylux product UUIDs (product.id). The result is still the shared inventory; sibling products in the same group appear on products.
Filters on inventories
inventoriesOptional filter object. Useful fields:
| Filter | Notes |
|---|---|
productId | Single product UUID |
productIds | Up to 250 product UUIDs; do not combine with productId |
merchantIds | Merchant UUIDs (if your key can see more than one) |
Stop sales policy
A stop sales policy is an InventoryPolicy whose config.type is STOP_SALES_POLICY.
config shape:
| Field | Values / meaning |
|---|---|
type | STOP_SALES_POLICY |
minInventory | Threshold quantity |
Inventory.salesStatus is derived from available quantity and the stop sales policy:
STOPPEDifavailableQuantityis at or below the stop salesminInventorySTOPPEDifavailableQuantityis<= 0- otherwise
LIVE
Read salesStatus for the current sellable state. Read the nested STOP_SALES_POLICY for the configured threshold.
When salesStatus is STOPPED, treat the inventory as unsellable. Sync it as 0 in the e-commerce platform even if availableQuantity in the inventory management system is still greater than 0 (those units sit at or below the stop sales threshold).
Updated 8 days ago
