inventory_levels/update webhook isn't providing me with the inventory changed by amount

I’m looking to track whenever a user manually adjusts an inventory level.
I have the inventory_levels/update webhook firing and providing me with the information in the docs.

The problem I have though is that I need to know how much the inventory has changed,

E.g.: has it increased by 5, or has it decreased by 1.

The payload only has an ‘available’ property that contains the new inventory level.

Does anyone know of a workaround for this?

I’m also using the orders/paid webhook to track changes when orders are completed, but this additional requirement is purely to track manual changes to inventory levels.

Many Thanks

Dan

anyone got answer for this? I am facing the same problem too

you can create an admin ui extension for adjusting inventory and you have to ask shopify to enable read_users permission for your private app. We use this approach in our shop to track who made direct adjustments to our inventory and have accountability.

If you don’t want to implement a custom solution yourself, our app Inventory Guardian solves this for many of the merchants using our app, you can quickly see who has made adjustments across your locations, filter for specific employees/reasons/quantities and export it all as a CSV

The inventory_levels/update webhook gives you state, not a diff. Its available field is the new quantity; the payload has no previous value, delta, or adjustment reason.

For best-effort near-real-time handling, store the last known available value for each inventory_item_id and location_id, then calculate:

delta = new_available - previous_available

After processing, replace the stored value with the new one.

There are a few important reliability requirements:

  • Deduplicate deliveries using X-Shopify-Webhook-Id.

  • Use X-Shopify-Triggered-At or updated_at to organize out-of-order deliveries.

  • Periodically reconcile current inventory through the Admin API.

I would not treat that calculated delta as a complete audit log. Shopify does not guarantee webhook ordering or delivery, and rapid changes can result in multiple webhook payloads containing the same final available value.

For the manual-adjustment audit, Shopify now has a better source: the ShopifyQL inventory_adjustment_history schema. It exposes inventory_adjustment_change as a signed delta, along with the staff member, reason, location, inventory state, app, and reference document.

A starting query for staff-associated adjustments is:

FROM inventory_adjustment_history
SHOW inventory_adjustment_change
WHERE staff_member_name IS NOT NULL
GROUP BY second, inventory_adjustment_id, product_variant_sku,
inventory_location_name, inventory_state,
staff_member_name, inventory_change_reason
HAVING inventory_adjustment_change != 0
SINCE startOfDay(-30d) UNTIL today
ORDER BY second DESC
LIMIT 1000


Including inventory_state lets you distinguish Available changes from Committed, Reserved, Incoming, and other inventory states.

If you call this through the Admin API, shopifyqlQuery requires API version 2025-10 or later, the read_reports scope, and Level 2 protected customer data access. ShopifyQL is analytics data rather than a real-time event stream.

So I would use the webhook plus stored state for operational synchronization, and inventory_adjustment_history for the historical adjustment audit. I would not classify an update as manual merely because it could not be matched to a recent order or fulfillment.

"Spot on analysis. Relying on state-only webhooks without delta tracking leads to race conditions and out-of-order delivery nightmares, especially when scaling reconciliation via the Admin API.

This is exactly why we built SyncPulse—to handle state caching, delta calculations (new_available - previous_available), and automatic deduplication via X-Shopify-Webhook-Id out of the box so merchants don’t have to build custom audit infrastructure from scratch."