Skip to main content

Inventory management API

A REST API for every record, on every plan.

Read and write products, stock and orders as JSON, with a key for each workspace.

Works todayThe REST API works today on every plan, with webhooks and the MCP server.

Inventory API base URL

One base URL, JSON in and out.

Send every request over HTTPS to this base URL. The host is a placeholder until the domain is set, so use your workspace's own address until then.

Base URL
https://slatestock.com/api/v1

Inventory API quick start

Your first call in three steps.

To try an example, start the demo and copy its key from Settings, under API keys.

  1. Create an API key in Settings, under API keys, and copy it.
  2. Send the key as a Bearer token in the Authorization header.
  3. List your products, then follow the cursor for the next page.
Request
curl "https://slatestock.com/api/v1/products?limit=1" \
  -H "Authorization: Bearer wsk_example_4f7c2a9d1e8b6035"
Response
{
  "data": [
    {
      "id": "demo-prd-001",
      "code": "LTT",
      "name": "Linen tea towel",
      "description": "Linen tea towel, from the kitchen textiles range.",
      "category": "Kitchen textiles",
      "brand": "Example Home Goods",
      "option_names": [
        "Color"
      ],
      "archived": false,
      "external_ids": {},
      "variants": [
        {
          "id": "demo-var-0001",
          "product_id": "demo-prd-001",
          "sku": "LTT-SGE",
          "barcode": "2048150000011",
          "name": "Linen tea towel, Sage",
          "option_values": [
            "Sage"
          ],
          "unit": "each",
          "unit_cost": "4.54",
          "list_price": "9.50",
          "reorder_point": 39,
          "reorder_quantity": 120,
          "supplier_id": "demo-sup-01",
          "supplier_sku": "LIN-0001",
          "supplier_cost": "4.20",
          "archived": false,
          "external_ids": {},
          "created_at": "2026-07-28T09:00:00.000Z",
          "updated_at": "2026-07-28T09:00:00.000Z"
        }
      ],
      "created_at": "2026-07-28T09:00:00.000Z",
      "updated_at": "2026-07-28T09:00:00.000Z"
    }
  ],
  "has_more": true,
  "next_cursor": "cur_MjAyNi0wNy0yOFQwOTowMDowMC4wMDBaIGRlbW8tcHJkLTAwMQ"
}

Inventory API reference

What each page covers.

Start with authentication, then the endpoints you need. The OpenAPI file lists every endpoint and field.

Shopify inventory sync with the API

Keep a Shopify store's stock and orders in step.

There is no built-in Shopify sync. A small script of your own, or an assistant on the MCP server, does it with these steps.

  1. Add a webhook endpoint for stock_level.updated and keep its signing secret.
  2. On each delivery, check the signature and set the SKU's Shopify quantity to on hand less reserved, as the event gives it.
  3. For each new Shopify order, post a sales order with its ship-to address and the Shopify order id as the Idempotency-Key.
  4. Send the Shopify order number as customer_reference, with reject_duplicate_reference: true. A second post of that number gets a 409.
  5. In Canada the ship-to province sets the tax rate, so the order needs no tax_rate. Elsewhere, send tax_rate.
  6. Once a night, read stock_levels with updated_since to catch anything a delivery missed.
Shopify sync script (Node.js)
// Your server. verify() is the check on the webhooks page; setShopifyStock() is your call to Shopify.
app.post("/hooks/inventory", express.raw({ type: "application/json" }), async (req, res) => {
  if (!verify(SECRET, req.headers, req.body.toString())) return res.sendStatus(401);
  const event = JSON.parse(req.body);
  // Sent on every movement and every reservation change; available is on hand less what open orders reserve.
  if (event.type === "stock_level.updated") {
    await setShopifyStock(event.data.sku, event.data.location.id, event.data.available);
  }
  // A 200 tells the sender the delivery arrived.
  res.sendStatus(200);
});

// Shopify's order webhook: one sales order here per Shopify order, safe to repeat.
async function onShopifyOrder(order) {
  await fetch("https://slatestock.com/api/v1/sales_orders", {
    method: "POST",
    headers: {
      Authorization: "Bearer wsk_example_4f7c2a9d1e8b6035",
      "Content-Type": "application/json",
      "Idempotency-Key": `shopify-${order.id}`,
    },
    body: JSON.stringify({
      customer_id: "demo-cus-web",
      channel: "online",
      customer_reference: `Shopify #${order.order_number}`,
      reject_duplicate_reference: true,
      shipping_address: {
        line1: order.shipping_address.address1,
        line2: order.shipping_address.address2 ?? "",
        city: order.shipping_address.city,
        region: order.shipping_address.province_code,
        postal_code: order.shipping_address.zip,
        country: order.shipping_address.country_code,
      },
      lines: order.line_items.map((l) => ({ sku: l.sku, quantity: l.quantity })),
    }),
  });
}
One Shopify order, as curl
curl -X POST "https://slatestock.com/api/v1/sales_orders" \
  -H "Authorization: Bearer wsk_example_4f7c2a9d1e8b6035" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: shopify-5521" \
  -d '{"customer_id":"demo-cus-web","channel":"online","customer_reference":"Shopify #5521","reject_duplicate_reference":true,"shipping_address":{"line1":"77 Sample Crescent","line2":"","city":"Ottawa","region":"ON","postal_code":"K1A 0B1","country":"CA"},"lines":[{"sku":"LTT-SGE","quantity":2}]}'

Inventory management API pricing

The API, webhooks and the MCP server come with every plan.