Replay Shopify Webhooks
Time: ~10 minutes | Difficulty: Beginner | Prerequisites: Shopify already flowing through Slashbin — see Onboard Shopify Webhooks.
TL;DR: Your endpoint was down during a flash sale, or you shipped a Golden Model change, or you added a warehouse destination after the fact. Shopify won't resend history and their REST API will rate-limit you if you try to reconstruct it. Slashbin replays the events it already stored — through the latest published model — and your destinations receive the re-processed payloads.
What You'll Build
Pick any historical window of Shopify events already sitting in your Slashbin project. Replay re-runs each event through the currently published Golden Model and delivers the result to every active destination. Your consumer sees clean, up-to-date JSON — including fields that didn't exist in the model when the event was first ingested:
{
"order_id": 6988309430586,
"order_total": 65.94,
"order_status": "paid",
"sales_channel": "jerky.com",
"fulfillment_center": "PDX-1",
"order_items": [
{ "sku": "JCB-BRISK-SD-3PK", "qty": 1, "price": 18.99 }
]
}The event above was originally captured with an older model that didn't produce fulfillment_center. Replaying it through the new model backfills that field — no Shopify API calls, no re-consenting the merchant.
The Problem
Shopify treats webhooks as fire-and-forget. Once they hand off an event, their reliability contract ends. That leaves you exposed in three common situations:
Your endpoint was down during a flash sale. Shopify tried a few times, hit non-2xx responses, moved on. The orders still exist in Shopify, but the orders/paid events that would have driven your downstream systems are gone from their outbound queue.
You changed your Golden Model. You added a fulfillment_center field, or tightened order_total to a decimal-safe cast. Historical events already delivered to your endpoint were computed with the old model — they're stale.
You added a new destination. Data warehouse, CRM, ops dashboard — it needs the last 30 days of orders, and Shopify only delivers going forward.
The "obvious" fix is to reconstruct from Shopify's REST API: GET /admin/api/2024-01/orders.json?updated_at_min=.... That path is a trap:
| Reconstruct via Shopify REST | Replay through Slashbin |
|---|---|
Rate limited (Shopify's leaky-bucket cap on /orders.json) — a large backfill takes hours | Rate limits don't apply — events are already stored at the gateway |
| Rebuilds objects, not the webhook payloads your handler expects | Re-delivers the exact webhook shape your Golden Model produces |
| Doesn't apply your model — you still have to run the transform yourself | Runs the currently published model on every event |
| Can't target one destination — you re-implement the fan-out logic | Delivers to every active destination just like a live event |
The Solution
Because every Shopify event flows through Slashbin, every event is already stored. Replay walks that history, re-runs each event through the latest published Golden Model, and re-delivers the result to your destinations. The steps below assume Shopify is already sending to a Slashbin ingestion URL — if it isn't, run the Onboard Shopify Webhooks recipe first so events are being captured.
Step 1: Select the Historical Window
Open your Shopify project in the Slashbin Console and go to the event history. Filter to the exact slice of history you want to re-run:
- By time range — the window your endpoint was down, or the window a new destination needs backfilled.
- By topic — for example, only
orders/paidandorders/updated. - By destination — replay only what a specific destination missed, without disturbing others.
This selection is what will be replayed. The events themselves are untouched — replay is a re-delivery, not a rewrite.
Step 2: Publish the Model You Want Applied
Replay always uses the currently published Golden Model. If you're replaying because you changed the model, publish the new version first.
Open the Transformation IDE, confirm the new field mappings, and click Publish. The version increments and becomes the active model — see Golden Model for how versioning and validation work. Any replay from this point forward runs through this version.
Unpublished models don't drop events — they land in the Dead Letter Queue — so it's safe to iterate the model and then trigger replay when it's right.
Step 3: Replay Through the Latest Published Model
With the window selected, click Replay. For each event in the window, Slashbin:
- Re-runs the raw stored webhook through the currently published Golden Model.
- Applies destination-level routing (see Fan-Out Routing) to deliver the result to every active destination.
- Retries per destination with the same backoff and DLQ semantics as live traffic — see Replay & Retry.
Slashbin has replayed windows in the tens of thousands of events in a single operation without touching Shopify's REST API. The bottleneck is your destination's throughput, not the gateway.
Step 4: Confirm Destinations Received the Re-Processed Events
Watch delivery status per destination in the Console. A replayed event looks the same to your endpoint as a live one — same signed payload, same headers — with a replay marker so your consumer can log it distinctly if you want to.
Newest-wins supersede logic. If live traffic is still arriving while a replay runs, replayed events for the same order_id won't clobber a newer state. Slashbin's supersede logic keeps the newest observed state for a given entity, so replaying a five-hour window on top of live traffic is safe.
Your handler should already be idempotent (Shopify may deliver duplicates in normal operation), so replays don't require any code change on your side.
Before & After a Model Change
Original event (delivered under old model):
{
"order_id": 6988309430586,
"order_total": 65.94,
"order_status": "paid",
"sales_channel": "jerky.com",
"order_items": [
{ "sku": "JCB-BRISK-SD-3PK", "qty": 1, "price": 18.99 }
]
}Same event, replayed after adding fulfillment_center to the Golden Model:
{
"order_id": 6988309430586,
"order_total": 65.94,
"order_status": "paid",
"sales_channel": "jerky.com",
"fulfillment_center": "PDX-1",
"order_items": [
{ "sku": "JCB-BRISK-SD-3PK", "qty": 1, "price": 18.99 }
]
}The raw Shopify payload is unchanged. The Golden Model produced a new field. Every downstream consumer picked it up on replay.
Why Slashbin vs a Raw Handler
- Replay is retroactive, not reconstructive. You fix the model once, replay history, and every destination receives the re-processed events. No Shopify REST backfill scripts.
- No rate limits. Slashbin is replaying its own storage, not calling Shopify. Backfills that would take hours against Shopify's leaky-bucket cap run at destination speed.
- The exact webhook shape your handler expects. Replay re-delivers the Golden Model output — not raw REST objects that your handler doesn't know how to consume.
- Supersede-safe next to live traffic. Newest-wins state means you don't have to freeze live delivery to run a replay.
Next Steps
- Define or update the shape of your replayed data — see Golden Model.
- Route replayed events to more than one destination — see Fan-Out Routing.
- Learn the DLQ and per-destination retry semantics that replay uses — see Replay & Retry.
- Browse every supported source and destination on Integrations.