
A store has three shirts. One location holds one shirt, another holds two. An order for three arrives, and Shopify assigns the whole line to the first location, which finishes the day reading negative two.
Nothing was oversold in aggregate. The store had three, the customer bought three. The negative number is an artifact of how orders get routed, and it has nothing to do with any setting anyone turned on. Shopify publishes that exact example in its own fulfillment documentation.
That’s the shape of the problem. Cycle counts, reorder points and forecasting don’t touch it. The failures that cost money during peak are structural, they live in the platform’s own model, and none of the three below is a counting error.
Every number below links to the Shopify page it came from, accessed September 8, 2026.
Shopify Inventory Management Runs On Two Vocabularies
The Shopify admin displays five inventory states. The GraphQL Admin API exposes eight. Your merchant and your developer are reading different taxonomies of the same shelf, which is why they disagree about what’s in stock and why neither of them is wrong.
The Admin Shows Five States. The API Has Eight.
Shopify’s Help Center defines the five merchant-facing states as On hand, Available, Committed, Unavailable and Incoming, with On hand described as the total of Committed, Unavailable and Available. The developer documentation for inventory management apps lists eight: incoming, on_hand, available, committed, reserved, damaged, safety_stock and quality_control.
The admin’s Unavailable bucket is four API states wearing one label. Shopify says so on both pages independently: the API reference repeats, on reserved, damaged, safety_stock and quality_control, that quantities in those states display as Unavailable to merchants tracking inventory in the admin.
| API state | What it holds | Admin label | Writable through the Admin API |
|---|---|---|---|
| incoming | Units on their way to a location, not physically present there | Incoming | No. Derived from transfers, purchase orders and apps |
| on_hand | Everything physically at the location, equal to the sum of the six states below | On hand | Settable as an absolute value |
| available | Units a merchant can sell | Available | Yes, absolute set or delta adjust |
| committed | Units set aside against a placed but unfulfilled order, a draft-order reservation, or a transfer marked ready to ship | Committed | No. Shopify-managed only |
| reserved | On-hand units temporarily set aside, for example for a hold or an inspection | Unavailable | Yes, adjust or move |
| damaged | On-hand units not sellable or usable due to damage | Unavailable | Yes, adjust or move |
| safety_stock | On-hand units held back to guard against overselling | Unavailable | Yes, adjust or move |
| quality_control | On-hand units in inspection and not sellable until it clears | Unavailable | Yes, adjust or move |
The two arithmetics are the same equation at different resolutions. Admin On hand is Committed plus Unavailable plus Available; API on_hand is available plus committed plus reserved plus damaged plus safety_stock plus quality_control. Substitute the four states that make up Unavailable and the two lines are identical. Incoming sits outside both totals, because neither page counts stock that hasn’t landed.
Shopify names seven of the eight states as mutually exclusive, and on_hand isn’t one of them, because on_hand is the sum of six of the others. Getting that backwards produces a reconciliation script that double-counts every unit in the warehouse.
There’s one seam worth stating precisely. The admin’s fourth unavailable reason is labeled Other, described on the adjusting inventory quantities page as inventory unavailable for a reason you’ve determined, while the API’s fourth unavailable state is reserved. Shopify doesn’t state anywhere we read that those two are the same field, so treat the mapping as undocumented as of September 8, 2026 rather than assumed.
Committed Is Shopify-Managed And Never Writable
You can’t use the Admin API to adjust or move inventory quantities in the committed state. Shopify manages it through order creation, order fulfillment, draft-order reservations, and transfers marked ready to ship, and it says so in the limitations section of the inventory management apps guide.
That single restriction explains a whole category of ERP-driven overselling. An ERP that thinks in one “quantity on hand” number can’t push that number to Shopify, because Shopify is holding units in committed against orders the ERP may not have ingested yet. Push raw on-hand and you overwrite the arithmetic, restoring units that are already spoken for. This is the mechanical reason connecting Shopify to an ERP has to be designed around who owns which number, not around which fields map to which.
Does Shopify hold inventory for a shopper during checkout? The documented commit point is order placement: Shopify decrements available and increments committed when an order is placed, then decrements committed on fulfillment. A time-boxed hold that runs while a shopper sits on the checkout page is not documented on any Shopify page in our sourcing as of September 8, 2026, and neither is whether adding to cart reserves anything. The one expiring reservation Shopify does document for merchants to control is reserveInventoryUntil on draft order creation, which takes a datetime and applies to draft orders rather than checkout.
Two mutations, two ownership models, both stated by Shopify. Absolute sets are documented for systems that act as the source of truth for inventory quantities; deltas are for everything else. The manage quantities and states guide puts it plainly: “If you don’t care about the current quantity because you’re the source of truth, then you don’t need to implement compare and swap and should opt out.” If a team can’t say which one their system is, it shouldn’t be writing absolute values into a live catalog.
Multi-Location Routing Oversells Your Shopify Inventory On Its Own
Shopify’s fulfillment documentation states the routing rule directly: if a location has enough inventory to fulfill an entire order, the order goes there, and if no single location can fulfill the order, it’s split across multiple locations or the highest-priority location oversells the product.
Read the second half again as a mechanism rather than an exception. Shopify will split line items across locations. By default it won’t split a single line item’s quantity. An order for three of one SKU can’t be sourced one from A and two from B, so when no location holds three, the highest-priority stocked location takes all three and goes negative.
That’s the negative two. Shopify’s example table on the same page extends it: with New York holding one shirt, orders for six and for seven shirts both land as oversold at New York, assigned to the highest-priority location where shirts are stocked.
Why is my inventory negative when I never turned on overselling? Because per-location depth thinned below order size. Peak is exactly when that happens: order quantities rise, stock spreads across more locations as you pre-position for shipping speed, and “no single location can fill this” stops being an edge case. The number isn’t a counting error, and no amount of cycle counting prevents it.
Continue Selling Is The Second Cause, Not The First
The setting exists and it matters. Shopify’s selling when out of stock page defines out of stock as tracked inventory at zero or below, and the Continue selling when out of stock option as the way to let customers buy past that point. In the API it’s the inventoryPolicy field on a product variant, with the enum values CONTINUE and DENY meaning customers can and can’t buy after it’s out of stock.
It’s a per-variant setting, which makes auditing it across the catalog a finite task rather than vague advice. Shopify lists legitimate reasons to use it: preorders, stock arriving soon, selling first and ordering later, and not tracking real quantities in Shopify at all.
The POS carve-out gets misread constantly, so state it carefully. Shopify says Continue selling when out of stock doesn’t apply to orders placed from Shopify POS, that staff can keep selling when available inventory reaches zero and below, and that POS warns staff before they sell an item that isn’t available. The setting doesn’t govern POS. POS staff can sell past zero either way, with a warning first.
Online Quantity Is Not Your Total Shopify Inventory
Ecommerce inventory management has three different correct answers to “how many do we have,” and merchandising, warehouse and the storefront each use a different one. Total inventory counts stock at every location, including the ones that don’t fulfill online orders. Online quantity counts only locations set to fulfill online orders. And sellableOnlineQuantity on the ProductVariant object is described as the total sellable quantity for online channels, which Shopify notes doesn’t represent total available inventory or capture limitations based on customer location.
Shopify’s fulfillment page spells out the consequence: preventing a location from fulfilling online orders removes that location’s inventory from a product’s online quantity, and online quantity is the number displayed to customers when you show inventory levels. That location’s stock can still fulfill draft orders and orders from other sales channels.
Why does my product show out of stock when I have stock? Shopify answers this one itself. If your online-fulfilling location sits at zero or below while a location that doesn’t fulfill online orders holds available inventory, the item still shows as out of stock to customers, and you have to add stock to the online-fulfilling location to make it buyable. A retail-only store quietly holding forty units doesn’t help a storefront reading zero.
Inventory also doesn’t pool. The multi-location inventory page states that each location’s inventory is independent and can’t be shared or pooled with other locations, that a new product starts at every location with a quantity of zero, and that a product must be active at a minimum of one location to be sellable.
How many locations can I have? Shopify’s location setup page publishes active location limits by plan: 2 on Starter, 10 on Basic, 10 on Grow, 10 on Advanced, and 200 on Plus. Deactivated locations don’t count against the limit, and apps that physically stock inventory for you, including dropshipping apps and third-party logistics services, are treated as locations without counting toward it. The page lists those five plans and stops, so a limit for Shopify for enterprise isn’t documented there as of September 8, 2026.
Note where the jump actually is. Basic, Grow and Advanced share the same figure, and the step change happens at Plus.
Five Of Eight Inventory States Fire No Webhook
Shopify publishes six inventory webhook topics: create, update and delete on inventory items, and connect, disconnect and update on inventory levels. Directly above that table, the inventory management apps guide notes that changes to the committed, reserved, damaged, safety_stock and quality_control states don’t trigger webhooks.
Five of the eight states are silent. The one your peak integration most wants to observe, stock being committed against an order that just landed, produces no inventory webhook at all. A 3PL polling inventory_levels/update sees the available movement and has no event stream describing the commit, and every safety-stock, damage and quality-control adjustment your own warehouse app writes is invisible to every other subscriber.
Why Shopify Inventory Tracking Needs A Reconciliation Job
Shopify’s own webhooks overview removes the ambiguity about how much to trust the event stream:
Your app shouldn't rely on receiving data from Shopify webhooks. Webhook delivery isn't always guaranteed, and your app can miss or mishandle events for other reasons, such as handler failures or downtime. For redundancy, use reconciliation jobs to periodically fetch data from Shopify so that your app stays consistent with Shopify's data.
Ordering isn’t guaranteed either, within a topic or across topics for the same resource, and Shopify recommends organizing on the X-Shopify-Triggered-At header or the payload’s updated_at. The implementation it suggests is the whole design: query with updated_at filters for everything changed since the last run.
The delivery mechanics tighten the case. Shopify’s HTTPS subscription page documents a one-second connection timeout and a five-second timeout for the entire request, treats any response outside the 200 range including 3XX codes as an error, and retries 8 times over the next 4 hours. After 8 consecutive failures the subscription is automatically deleted if it was configured through the Admin API, with warning emails going to the app’s emergency developer email address.
Not paused. Deleted. Five seconds is generous until your own handler is queueing behind a traffic spike, and eight consecutive failures inside a four-hour window during peak don’t degrade your inventory feed, they remove it, with the only notice landing in whatever address sits in that emergency contact field. Checking that address costs a minute and it belongs in the Black Friday readiness sequence alongside the rest of the pre-peak checks.
We build these integrations, and the argument we make to every client is the same: the reconciliation job ships with version one, not as a hardening phase scheduled for January.
Two Traps In Shopify's Inventory API
Shopify’s inventory documentation currently holds two traps: one page that contradicts its own schema, and one behavior change documented for developers and merchants on pages neither audience reads together.
The first is on the inventorySetQuantities reference page at API version 2026-07. The mutation’s prose description still describes a compare-and-set built on a compareQuantity field with an ignoreCompareQuantity opt-out, and several of the page’s own code examples pass ignoreCompareQuantity: true. The embedded schema block on that same page contains neither field. Concurrency control in 2026-07 is changeFromQuantity on the per-item input, so a developer who copies the examples writes against fields the schema doesn’t define.
Read the schema block, not the prose, and re-check the page before you build, because Shopify may correct it. The mechanism itself is worth using: changeFromQuantity lets you declare the quantity you expect to find before your change applies, and the mutation fails with a CHANGE_FROM_QUANTITY_STALE error rather than overwriting concurrent work. Shopify’s own worked example runs 100 red shoes down to 90 while 20 sold underneath, losing 20 units silently. Compare and swap is implemented on several mutations, including inventoryAdjustQuantities, inventoryMoveQuantities, inventorySetQuantities and productVariantsBulkUpdate.
Quantity Writes That Succeed And Sell Nothing
The second trap is a behavior change rather than a documentation error, and it’s the quieter of the two. Before API version 2026-04, the three quantity mutations returned an ITEM_NOT_STOCKED_AT_LOCATION error when the inventory item wasn’t stocked at the location. From 2026-04 onward, those mutations can create an inactive InventoryLevel and store the quantity, and the item isn’t available for sale or fulfillment from that location until it’s activated there.
The API returns success. Your logs are clean. Your integration reports that it wrote 400 units into the Denver warehouse, and Denver sells zero of them.
The merchant-side symptom is documented on a completely different page for a completely different audience. Shopify’s multi-location inventory page states that a dash in the Available column means the product is inactive at that location, so it isn’t sellable or fulfillable from there even though an On hand quantity is recorded, and that this commonly happens after transferring inventory, receiving a transfer, adding a new store location, or updating quantities with the bulk editor or an inventory CSV file, because those actions record quantity without changing activation. Two pages, two audiences, one silent failure.
The fix is to pair every quantity write with explicit activation through inventoryActivate, or the bulk toggle when one item needs activating across several locations. Activating a level that already holds quantities without supplying available or on-hand values preserves what’s there.
You can’t solve that ordering inside a bulk import. Shopify’s bulk import documentation states that the GraphQL Admin API doesn’t serially process the contents of the JSONL file and warns against relying on a particular sequence of lines. “Set the quantity, then activate the item” isn’t expressible as two adjacent lines in one file, and on 2026-04 and later, attempting it is how you produce a warehouse full of dashes the week before peak.
The other bulk numbers, attached to their subjects: from API version 2026-01 and higher each app can run up to five bulk mutation operations concurrently per shop, the operation has to complete within 24 hours or it’s stopped and marked failed, the mutation passed in is limited to one connection field, and the JSONL file can’t exceed 100MB.
Shopify Inventory Integrations Pinned To 2025-10 Have Under Six Weeks
Shopify’s versioning page documents a new API version every three months at the start of the quarter, each stable version supported for a minimum of 12 months with at least nine months of overlap between consecutive versions. The current stable version is 2026-07, released July 1, 2026 and accessible until July 16, 2027 at 15:00 UTC. 2026-10 exists today as the release candidate, which Shopify flags as potentially including backwards-incompatible changes and not recommended for production.
| Stable version | Release date | Accessible until |
|---|---|---|
| 2025-10 | October 1, 2025 | October 16, 2026, 15:00 UTC |
| 2026-01 | January 1, 2026 | January 16, 2027, 15:00 UTC |
| 2026-04 | April 1, 2026 | April 16, 2027, 15:00 UTC |
| 2026-07 (latest) | July 1, 2026 | July 16, 2027, 15:00 UTC |
| 2026-10 (release candidate) | October 1, 2026 | October 16, 2027, 15:00 UTC |
2025-10 stops being accessible on October 16, 2026. That’s under six weeks from now and it lands in the middle of peak preparation, on the version a great many inventory integrations were pinned to a year ago and never revisited.
Shopify doesn’t break you outright. If your app targets an inaccessible version it falls forward and responds using the oldest accessible stable version, and responses carry an X-Shopify-API-Version header reflecting the version actually used. If that header differs from what you requested, you’re pinned to something inaccessible and Shopify has quietly moved you.
Reading that header on one response is a free pre-peak audit, and it’s Shopify’s own suggested check. Webhook payloads are versioned the same way and carry the same header.
Falling forward means your integration changes behavior on Shopify’s schedule rather than yours, in the same window where inventory writes carry the most consequence. Two version-scoped changes make that concrete for inventory work specifically. Scheduled inventory changes are being phased out: inventorySetScheduledChanges isn’t available in the 2026-07 Admin API, scheduledChanges on InventoryLevel is deprecated, and scheduling requires an API version between 2024-01 and 2026-04. Anything that scheduled incoming-to-available transitions breaks on the version that’s latest today, and Shopify’s own note adds that the mutation never changed quantities on its own anyway.
The second is idempotency. Shopify’s caution box on the inventorySetQuantities page states that as of 2026-01 the mutation supports an optional idempotency key through the @idempotent directive, and that as of 2026-04 the key is required. Per Shopify’s idempotency documentation, it tracks idempotency keys for 24 hours, after which duplicates are treated as separate operations, so a dead-letter queue that retries a failed adjustment two days later has no protection and double-applies the change.
Stocky Is Gone And Shopify Inventory Management Moved Into The Admin
Shopify’s transition page states it in one line: “Stocky is no longer available as of August 31, 2026. You now need to manage inventory in the Shopify admin and Shopify POS.” The app was delisted from the App Store on February 2, 2026, and the Stocky APIs stopped working on August 31, 2026, so third-party tools that integrated with it need rebuilding against Shopify’s inventory system.
Four workflows move into the admin: moving inventory across locations with transfers, tracking and receiving purchase orders from suppliers, adjusting inventory quantities, and reporting on historical inventory changes.
The migration terms are where the calendar bites. Shopify says you’ll have read-only access to export your data for at least 90 days after August 31, 2026, which puts the earliest end of that window in roughly late November. Historical data such as old purchase orders and stocktakes doesn’t move into Shopify automatically, historical purchase orders can’t be imported, and suppliers can’t be exported from Stocky at all.
Shopify also notes that native CSV upload for purchase orders only adds product line items to a new draft purchase order and can’t import past statuses, received quantities, or supplier links. So the export window closes across peak, and a POS-heavy retailer who hasn’t pulled their data yet will be doing it, if at all, during Black Friday week. Export it this month.
The replacement primitives exist and they aren’t ready for production. Shopify’s physical inventory feature preview, announced in a changelog dated July 17, 2026, adds bins, counts and purchase orders as API primitives. It runs on the unstable version of the GraphQL Admin API, only stores with the preview enabled can call it, and Shopify says the APIs are under active development and subject to change.
The model is additive. Bins add a finer grain inside a location, so an item’s on-hand can be split across the bins where it’s physically stored, and the location’s total on-hand equals the unbinned quantity plus the sum of every bin quantity. Existing calls still work, with quantity set at the location level landing in the unbinned quantity, and the location-level aggregates for available, committed and on-hand stay unchanged.
For the automation gap Stocky leaves behind, Shopify’s guidance on its own transition page is to set up automated low-stock alerts using Shopify Flow, and it markets Sidekick as able to answer reordering questions and draft the purchase order or transfer for you based on sales data. That Sidekick paragraph is Shopify promoting its own product on its own migration page, so read it as a vendor capability claim rather than a measured outcome. What it does establish factually is that reorder suggestions live in Sidekick, not in a report.
The 28-Day Window Behind Shopify's Inventory Reports
Shopify’s native inventory reports are accurate. They’re also answering a different question than the one you’re asking in November, and the reason is a window you can’t change.
Days of inventory remaining is calculated as the total quantity of items still in inventory divided by the average quantity of items sold per day, and Shopify states that a variant’s average quantity sold per day is calculated on its sales over the last 28 days. ABC product analysis grades each variant on the percentage of revenue it contributed over the last 28 days, and Shopify says on the same page that the timeframe cannot be adjusted.
Run either report on November 10, 2026 and the trailing window covers October 13 through November 9. It contains no Black Friday, no Cyber Monday, and no promotional traffic. It will tell you, correctly, how long your stock lasts at pre-peak demand.
Sell-through lags too. Shopify calculates sell-through rate as total quantity sold divided by total quantity sold plus total quantity still in inventory, and discloses that due to data latency and processing times the most recent period the report can return is approximately two days prior to the current date, closer to three days for earlier time zones such as UTC +14:00. During the fastest 96 hours of your year, the number you’re reading describes a period that ended two days ago.
Two more constraints shape what you can do with any of it. Per Shopify’s report types index, reports display a maximum of 1,000 rows, with totals still calculated across all rows, which means a large catalog needs an export before it can be analyzed. Historical data for inventory-based metrics goes back only to October 1, 2023, and historical inventory for deleted locations doesn’t appear in inventory reports since only active locations show in historical reporting data. Deleting a location stops its history appearing in the reports.
None of that is a defect. These are month-end and trailing-average instruments, they’re good at describing what your catalog normally does, and peak planning needs a multiplier applied on top that Shopify doesn’t supply. Build the multiplier from last year’s own numbers, before the window you’re comparing against fills up with this year’s peak.
Safety Stock: Shopify Inventory Management Gives You The Shelf, Not The Rule
Shopify supports safety stock as a state, and the distinction between a state and a policy is the whole section.
What exists is real. There’s a first-class safety_stock state defined as on-hand units set aside to help guard against overselling, a matching safety_stock value among the 17 adjustment reasons Shopify documents for the reason field, and inventoryMoveQuantities to move units from available into safety_stock and back. Shopify’s own move-table descriptions frame those transitions as insuring against fluctuations in demand. The admin exposes the merchant-facing equivalents through the Safety stock unavailable state and the Adjust by flow.
What isn’t documented as of September 8, 2026 is the rule layer. A safety-stock threshold or reorder point per variant isn’t documented in the admin. Automatic replenishment of safety_stock isn’t documented either, so moves are explicit mutations or explicit admin adjustments. A native low-stock notification isn’t documented: Shopify’s inventory overview tells merchants to install an inventory alert app from the App Store or to use Shopify Flow.
So reserving peak buffer is a mechanical operation you perform, or one you automate yourself by pairing inventoryMoveQuantities with your own threshold logic. That’s a build decision to make in September, not a setting to find in November.
One caution, and it’s the reason buffer gets quietly reversed by whoever notices the number first. Moving units into safety_stock reduces available, available drives online quantity, and online quantity is what customers see. Buffer isn’t free. It’s a decision to display a smaller number on purpose, and everyone who reads that number needs to know it was deliberate.
Store Inventory Control Levers You Can Set Before Peak
Shopify documents five order routing rules, applied in sequence, with each rule operating on the results of the previous one. Order routing requires two or more active locations. Per Shopify’s understanding order routing page, the default strategy optimizes for fulfillment from the closest location within the destination market that has all the items in stock.
Straight Lines, Ranked Locations, And A Boolean Metafield
The five rules are minimize split fulfillments, stay within the destination market, ship from the closest location, use ranked locations, and use location metafields. Shopify’s understanding order routing page documents that ranked locations and location metafields can each be added to a strategy more than once, and that ranked locations work by group, so every location in the topmost group shares a ranking of 1.
The metafield rule is the peak lever, and Shopify supplies the example itself: define a boolean location metafield named has_capacity and prioritize locations that have capacity to fulfill orders. A warehouse drowning on the Monday after Black Friday gets de-prioritized by flipping one metafield, with no inventory moved and no location deactivated. That’s a change you can make at 2am, and it only exists if someone created the metafield and added the rule beforehand.
Read the closest-location rule literally. Shopify measures distance in a straight line and says so, notes that straight-line distance isn’t driving distance, recommends applying the rule last, and states that when two locations share an address the older one is prioritized. A location across a bay or a mountain range can beat one an hour closer by road.
Local pickup has its own failure mode under load. Shopify’s pickup in store page says pickup is available by default only when the entire order is in stock at the pickup location. Configure store transfers and pickup stays available when the location runs dry, but the checkout displays an estimated pickup time that accounts for the transfer, so the customer’s expectation gets set against a transfer now competing with everything else the store is doing.
Two admin habits are worth fixing now because neither can be repaired later. Shopify’s adjusting-inventory page documents that when you use the bulk editor you don’t need to specify origin and destination, and that a record of your inventory movements isn’t tracked when you use it. The fastest manual fix during a peak incident is the one path that leaves no movement history, which is precisely the history you’ll want on the Monday after.
The other is the audit trail. referenceDocumentUri is accepted on inventoryAdjustQuantities, inventorySetQuantities and inventoryMoveQuantities, it takes a freeform URI recording why a change happened, and Shopify’s own examples are shaped like gid://erp/StockAdjustment/ADJ-2024-001 and gid://3pl-system/CycleCount/CC-2024-0125.
It surfaces in the adjustment history merchants see and in the inventory adjustment reports. Without it, the history says an app did it; with it, the history names the purchase order or sync job. It costs nothing to add, and there’s no documented way to attach one to an adjustment that’s already recorded.
One more cheap catch for anyone syncing from an external system: Shopify treats SKU strings as case-sensitive, and its fulfillment service documentation states that SKUs returned from the fetch stock endpoint are matched to Shopify product SKUs respecting case. ABC-123 and abc-123 are two different SKUs here, and plenty of ERPs are case-insensitive on item codes.
That same page documents a full inventory request happening once every hour to keep Shopify current with a remote fulfillment service. Scope that number carefully: it’s the fulfillment-service polling cadence for legacy fulfillment service apps, not a general statement about how often Shopify syncs with 3PLs, and it doesn’t apply to a 3PL writing through the Admin API. Where it does apply, an hour is several product lifetimes during a flash sale.
The Shopify Inventory Management Setup That Holds Through Peak
Everything below traces to a Shopify page cited above. It’s a sequence, not a menu, and most of it is configuration rather than development.
- Audit the Continue selling setting across the catalog, because it's set per variant
- Audit which locations have "Use inventory at this location to fulfill online orders" turned on, because that toggle defines the number customers see
- Accept that routing oversells when no single location can fill an order, and staff your incident response for negative numbers that aren't errors
- Create a boolean capacity metafield on every location and add the routing rule that reads it, before you need it
- Check the emergency developer contact address on every app writing inventory, because that's where the only warning goes
- Read the API version header on one response from every integration and confirm nothing is pinned to a version about to go inaccessible
- Find anything that schedules inventory changes, because scheduling doesn't exist in the current stable version
- Pair every quantity write with an explicit activation call, or expect dashes where stock should be
- Send a reference URI on every adjustment starting now, since it can't be added retroactively
- Keep the bulk editor out of peak-week corrections, because it records no movement history
- Set safety stock by explicitly moving units out of available, and tell merchandising the displayed number is smaller on purpose
- Export your Stocky data, including a manual capture of suppliers, since suppliers can't be exported
The reconciliation job is the one line item that’s real engineering, and it’s the one that pays for itself in a single incident. Query with updated_at filters for everything changed since the last run, on a schedule, against every location. Shopify tells you to build it. Five of eight states give you no other way to see the shelf.
We end up in this decision on most replatforms and most ERP builds, and the question is always the same: who owns the number. Answer that first and the API tells you which mutation to use, whether to implement compare and swap, and what your reconciliation job is allowed to overwrite. Answer it late and you find out during peak.
Scope Your Shopify Inventory Management Before Peak, Not During It
You built a business that can handle the volume. The setup underneath it should be able to prove that, at 2am on the Saturday after Black Friday, with a negative number on a dashboard and someone asking what happened.
Every fix above is cheap in September and expensive in November. The metafield, the activation pairing, the reference URIs, the reconciliation job: each one covers what happens after you build it, and none of them reaches backwards over the orders that already landed.
Talk to us about scoping your inventory architecture before peak. We’ll map your locations, routing rules, integrations and API versions against what the platform actually does, and hand you the gaps in priority order. No assumptions. No selling you work you don’t need.
If you want to see how we work before you talk to us, here’s how BLKDG works as a Shopify Partner.
Not sure where the gap is? That's exactly what the Digital Marketing Growth Audit is for.
A free, no-obligation look at where your site can win more traffic and conversions, with a clear digital marketing roadmap to get there. Just a straight read on where your digital presence stands and where it's headed.



