← the work

SUPPLIER API → SHOPIFY

Live stock, no more overselling

Your supplier knows exactly what's in their warehouse. Your Shopify store is guessing. Here's how we'd keep the two honest with each other — without ever letting a bad feed empty your shelves.

teardown · 7 min read · Supplier feed/API + Shopify Inventory API

The problem

A customer buys something at 2pm. It sold out at your supplier at 11am. Now you're sending an apologetic "actually, that's not available" email, refunding the order, and watching a first-time customer decide not to come back. Multiply that across a catalogue you don't physically hold, and overselling becomes a steady tax on your reputation.

The usual fix is someone exporting a spreadsheet from the supplier each morning and bulk-editing Shopify — slow, already stale by lunch, and exactly the kind of repetitive job that gets skipped on a busy week.

If you dropship or hold little stock of your own, your supplier's stock is your stock. Shopify should know what they know, automatically.

What "fixed" looks like

When your supplier runs low, Shopify knows within minutes and stops the sale — or shows "backorder" if that's how you want to play it. When they restock, your products quietly come back available. The morning spreadsheet ritual is gone, and the "sorry, it's actually out of stock" email goes with it.

How we'd connect it

Most suppliers expose stock one of three ways: a REST API, a scheduled CSV feed, or (less often) a real-time webhook. We read whichever you've got on a sensible interval, match their SKUs to your products, and set Shopify's available quantity to match — accounting for a safety buffer so you're never selling the very last unit you can't confirm.

Supplier stock match SKUs sanity-check + buffer Shopify inventory

Set inventory, the safe way

Shopify tracks stock per location against an inventory item. We resolve each supplier SKU to its Shopify inventory item once, cache that mapping, then push quantities. Crucially, we apply a buffer and a floor before anything is written.

sync-stock.js
async function syncStock(supplierRows, mapping, locationId){
  for (const row of supplierRows){
    const item = mapping[row.sku];
    if (!item){ flagUnmatched(row.sku); continue; }  // don't guess

    const buffer = 2;                       // never sell the last 2
    const available = Math.max(0, row.qty - buffer);

    await shopify.inventoryLevels.set({
      location_id: locationId,
      inventory_item_id: item.inventoryItemId,
      available
    });
  }
}

For a large catalogue we batch this through Shopify's bulk/GraphQL path rather than firing thousands of individual calls — but the logic that protects you is the same.

The edge case that matters most

One failure mode dwarfs all the others, and it's the one a quick build forgets: a bad feed must never wipe your store.

// the guard that earns the whole project

If the supplier's API times out, returns an empty file, or ships a truncated export, a naïve sync reads "0 everywhere" and sets every product to out of stock. Your entire catalogue goes dark in minutes, and you don't notice until sales stop.

So before we write anything, we sanity-check the feed: is it roughly the size we expect? Did 90% of SKUs just drop to zero at once? If a feed looks wrong, we reject it wholesale, keep the last known-good state, and alert a human — we never let a broken upstream take the store down.

The other edge cases that bite

// the rest of the unglamorous, necessary work
  • SKU mismatches. Supplier codes rarely match yours perfectly. We build and maintain a mapping table, and unmatched SKUs get flagged for review — never silently dropped.
  • Safety buffers. A configurable buffer (and per-product overrides) so you're not selling stock that's about to vanish between syncs.
  • Backorder vs hide. Some products should keep selling on backorder; others should disappear at zero. That's a per-product decision we respect, not a global switch.
  • Multiple locations. If you hold some stock yourself and dropship the rest, we sync the supplier into the right location and leave your own counts alone.
  • Rate limits. Shopify's API throttles. We respect the leaky bucket and back off cleanly so a big sync finishes instead of getting cut off.
  • Freshness vs cost. Every 15 minutes is plenty for most stores; near-real-time is possible if the supplier supports webhooks. We'll right-size it rather than hammer their API for no reason.

Isn't there a stock-sync app for this?

There are plenty — Stock Sync, Syncee and similar will pull a supplier feed into Shopify, and if your supplier hands you a clean, standard file they're worth trying first. They start to creak the moment the feed is messy or the rules are yours: that's the gap we build into.

// where the line sits
a generic stock-sync app
  • Imports a supplier feed on a schedule against matched SKUs
  • Works well when SKUs line up and the file format is consistent
  • Updates quantities; usually stops there
  • Limited control when the numbers look wrong
where we get called in
  • Inconsistent SKUs and a supplier CSV that changes shape without warning
  • Safety buffers and sanity guards so a bad feed can't zero your whole catalogue
  • Stock split across the supplier and your own shelf or in-store sales
  • Right-sized refresh and clean back-off instead of hammering their API

What it'd take for you

The price hinges entirely on what your supplier gives you to work with. A clean REST API is straightforward; a daily CSV with inconsistent SKUs needs more mapping and guarding. Most of these land in the $6k–$20k range. The first thing we'd do on a fit call is look at exactly what your supplier exposes — that tells us almost everything.

Selling things you can't actually ship?

tell us who your supplier is · 20-min fit call

Book a fit call