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.

EnvironmentURL
Productionhttps://api.stylux.io/graphql
Staginghttps://api-stg.stylux.io/graphql
Developmenthttps://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:inventories for inventory and policy fields
  • read:products for nested product fields

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

FieldNotes
idStylux inventory UUID
inventoryIdOptional external / merchant inventory identifier
availableQuantityUnits available to sell
allocatedQuantityUnits already allocated
inventoryLevelStatusNONE, LOW, or SUFFICIENT
salesStatusLIVE or STOPPED
createdDate / updatedDateISO 8601 timestamps
productsPaginated grouped products (see below)
inventoryPoliciesPaginated 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 fieldNotes
idLink row UUID
positionOrder within the inventory group
productThe 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

Optional filter object. Useful fields:

FilterNotes
productIdSingle product UUID
productIdsUp to 250 product UUIDs; do not combine with productId
merchantIdsMerchant 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:

FieldValues / meaning
typeSTOP_SALES_POLICY
minInventoryThreshold quantity

Inventory.salesStatus is derived from available quantity and the stop sales policy:

  • STOPPED if availableQuantity is at or below the stop sales minInventory
  • STOPPED if availableQuantity is <= 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).


Did this page help you?