Type: Fix / Developer Guide · Stage: Optimize · Topic: AJAX Cart / Webhooks / Automation
On this page
Quick answer
As of October 12, 2026, Shopify no longer sends a carts/update webhook when a cart operation leaves the cart unchanged. Sending the same note, attributes, quantities, or other values again can return a normal cart response without producing a new webhook. That is not necessarily a failed cart request or a broken subscription. Shopify now sends the webhook for actual cart changes, rather than for every cart operation.
If an integration treats a carts/update delivery as the acknowledgment that a write succeeded, separate those two concepts. The response to the cart mutation tells the caller whether the request completed; the webhook tells downstream systems that cart state changed.
Why older cart-sync assumptions fail
Older integration examples sometimes use a write to “poke” a cart and then wait for the next webhook. A cart-recovery service might resubmit an existing attribute, an upsell script might repeatedly post the current quantities, or a customer-support tool might write the same cart note twice. Before this change, even a no-op operation could produce carts/update. After October 12, the second identical write does not qualify as a change.
This is an important distinction for monitoring. An absence of a webhook following a request does not prove that Shopify rejected the request. Equally, a webhook’s arrival does not prove that a specific request from your app caused it: another storefront or app process might have changed the cart.
Fix the integration, not the webhook
- Identify the trigger you actually need. If the requirement is “run after my cart API request,” use the resolved API response. If it is “run when the cart’s persisted contents or properties change,” use
carts/update. - Stop making no-op writes to trigger side effects. A write that repeats the existing values is no longer a reliable event generator. Do not force a fake note or attribute change to manufacture a webhook; that creates avoidable state changes and potential automation loops.
- Compare state before deciding to write. In a storefront script, read the cart and update only when the desired values differ. On a server, compare a normalized representation of the fields your service owns; do not compare timestamps alone.
- Make downstream processing idempotent. Webhook deliveries can be retried or duplicated independently of this change. Verify the signature and deduplicate deliveries using Shopify’s webhook delivery identifier; do not assume “one per change” means exactly-once delivery to your handler.
- Reconcile separately. If your system needs assurance that a cart still exists or matches an external session, schedule a targeted reconciliation or read the cart through an appropriate authorized API. Do not use an unchanged write as a heartbeat.
Storefront example: do not write the same cart note twice
For an Online Store AJAX Cart integration, a minimal pattern is to read the cart and only submit a note when it differs. Use Shopify’s locale-aware route root so the request works in localized storefronts:
const root = window.Shopify?.routes?.root || '/';
const cart = await fetch(root + 'cart.js').then(r => r.json());
const desiredNote = 'Gift receipt requested';
if ((cart.note || '') !== desiredNote) {
const response = await fetch(root + 'cart/update.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ note: desiredNote })
});
if (!response.ok) throw new Error('Cart update failed');
const updatedCart = await response.json();
// Use updatedCart here; do not wait for a webhook to confirm this write.
}
This is an illustrative storefront snippet, not a complete concurrency solution. A second tab or app can change the cart between the read and write. For external synchronization, use server-side logging and reconciliation. A storefront JavaScript client should never contain webhook signing secrets or Admin API credentials.
What to log when the webhook appears missing
Record the request method and endpoint, cart/session identifier where permitted, a safe hash of the before/after fields, the HTTP status, and the result of the write. In the webhook handler, record the shop, topic, delivery ID, signature-verification result, and whether the delivery was already processed. Avoid logging raw personal information or payment details.
Then compare three cases: an unchanged write, a genuine cart change, and a duplicate delivery. These are different operational events and should not share the same “webhook failed” alert.
Common misunderstanding
“My cart API returned 200 but no webhook arrived, so the subscription is broken.” Not if the operation left the cart unchanged. First inspect the resulting cart state.
“Shopify guarantees exactly one webhook delivery now.” No. The October change is about whether a no-op cart operation triggers an event. Delivery retries, duplicate deliveries, signature verification, and idempotent handlers remain necessary.
“This changes my theme’s cart drawer events.” The announcement concerns Shopify’s carts/update webhook. A theme’s custom JavaScript events, section rendering, and cart drawer refresh behavior are separate systems.
How to test this
- On a development store, subscribe a test endpoint to
carts/updateand log delivery IDs and timestamps. Verify webhook signature handling first. - Read a test cart, then submit the same note or attribute value without changing anything. Confirm the cart request succeeds and no new
carts/updateis expected for that no-op. - Submit a different value or change a quantity. Confirm the cart actually changes and the webhook handler receives the corresponding event.
- Repeat the same new value. Confirm your app no longer waits for a webhook as an acknowledgment.
- Replay a captured valid delivery in a controlled test to verify that your idempotency store prevents duplicate downstream work.
- Check monitoring: distinguish failed writes, unchanged writes, delayed deliveries, and handler failures. Deploy behind logging before removing any old fallback behavior.
Sources and further reading
- Shopify developer changelog: unchanged carts no longer trigger carts/update (October 12, 2026)
- Shopify Ajax API: Cart reference
- Shopify developer docs: webhook delivery structure and headers
- Shopify developer docs: webhooks
Documentation checked October 18, 2026.

