Skip to main content
Meridian delivers your app’s Shopify webhooks over Google Cloud Pub/Sub. Rather than each shop calling your endpoint directly, Shopify publishes events to a Pub/Sub topic and Meridian routes them to your app, a more reliable and replayable path for high-volume webhook traffic.

Webhook routing

For each app, Meridian manages which Shopify topics are subscribed and where they’re delivered:
  • the topics your app listens for,
  • the forward path each topic is delivered to in your app,
  • and whether Shopify accepted the per-shop subscription.
Per-shop subscriptions are reconciled automatically as shops install and uninstall, so you don’t register webhooks by hand for every store. A store that reinstalls within a minute or so of uninstalling is a special case: the reinstall finds the previous install’s subscriptions still in place, and Shopify deletes them shortly after. On an app deployed on Meridian with its session database, Meridian registers them again 2 and 10 minutes after it handles the uninstall. On an app hosted off Meridian, a change to the topic set reaches the stores that already installed it only when each one next authenticates (see Re-registering webhooks).

Registration status

On an app deployed on Meridian, saving the topic set registers every topic on each store that has the app installed. The Delivery column of the Webhooks table then shows where each topic stands:
  • Registering…: the registration is queued. It usually settles within seconds, and can take a few minutes while a deploy is running.
  • Registration failed: at least one store refused the subscription, or Meridian couldn’t reach that store at all (for example, its access token was revoked). Hover the label to read the reason, which names the store when it couldn’t be reached.
  • Registered · no events yet: every store accepted the subscription, and Shopify hasn’t sent an event yet.
  • No outcome recorded: no store reported back within 30 minutes of the save. Save any change on the Webhooks table to register every topic again.
Stores that uninstalled your app are left out.

Deliveries

The webhooks view lists recent inbound deliveries: topic, shop, status, attempts, and the response code your handler returned. This separates two failures that look identical from inside your code:
  • No delivery row for a topic means Shopify never sent it. Check the route and its registration.
  • A 4xx/5xx response code means it arrived and your handler rejected it.
The live delivery log and its throughput tiles refresh every 15 seconds while the Pub/Sub tab is visible. Returning to the tab refreshes them immediately, so you can trigger a webhook in another tab and see its delivery without reloading once Meridian has ingested the event. The webhook body and its HMAC headers aren’t shown in list views. Read a specific payload in the dashboard when you need one.

Retries and permanent failures

When your app can’t take a forward right now, Meridian tries again, up to three attempts in total, waiting at least 10 seconds and then 30 seconds between them. That covers a timeout or connection error, any 5xx, and 408, 425 and 429. Every other answer outside 2xx is final, including 3xx, 401 and 403. Meridian doesn’t retry it: the delivery is marked Failed after one attempt (the attempts column reads 1 / 3), and its error names the status and the path your app answered at. While a topic’s latest delivery failed this way, its row on the Webhooks tab reads Last forward failed: HTTP 404 (with the actual status). What to check:
  • 404, 405 or 410: the topic’s forward path points at a route your app doesn’t serve. Change the path on the Webhooks tab, or add that route to your app.
  • 401 or 403: your app most likely couldn’t verify the forward’s signature. Check that MERIDIAN_WEBHOOK_SECRET holds this app’s current signing secret, then redeploy. See Rotating the signing secret.
  • Any other status: your handler refused the event. Check what it returns for that topic.
A fix applies from the next event on. A delivery that already failed isn’t sent again.
Last modified on October 7, 2026