An official webhook can replace an approved polling loop only when its declared coverage is enough for the business decision and a bounded reconciliation can detect the gaps it cannot prove away. For example, a merchandising operator may need to decide whether a public, authorized supplier change should be reviewed today. That is a current-state decision, not an audit that every intermediate change was observed. This guide gives the owner a local decision fixture: USE_WEBHOOK_WITH_RECONCILIATION, KEEP_APPROVED_POLLING, or HOLD.
It assumes the data source is already authorized. It is not advice to bypass a site, scrape an undocumented route, buy a proxy, or treat a webhook as evidence that a change never happened.
Start with the decision and its loss boundary
Write one decision sentence before changing the monitor: “When the official source says this listed offer changed, an operator reviews the current public offer before a campaign goes live.” Then name the harmful miss. If the campaign can wait until the declared retry window closes plus a team review margin, a current-state decision may tolerate that bounded delay. A compliance audit, dispute investigation, or every-event calculation does not: an event that was created and reversed before reconciliation may matter even when the current state looks unchanged.
| Question | Current-state review | Every-event requirement |
|---|---|---|
| What must be known? | The authoritative state at review time. | Each qualifying transition and its sequence. |
| Can a periodic authoritative read help? | Yes, if its scope and lag are accepted. | Only if the source offers a complete, retained event history that can be reconciled. |
| Safe default when proof is absent | HOLD or keep the approved poll. | HOLD; obtain a retained, auditable event history or narrow the task. |
No event received is not proof that nothing changed. A reconciliation read can establish a later observable state; it cannot reconstruct a transient history that neither the event feed nor the authoritative source retains. Keeping an approved polling baseline is likewise not proof of every transition: snapshots can miss a change that comes and goes between reads. If every-event completeness is required and the available route cannot meet it, hold the switch and escalate a separate auditable-feed design.
Make an official-event acceptance record
Obtain the provider’s current documentation and record the exact topic, subscription scope, payload version, stable delivery/event identifier, event timestamp meaning, authentication method, retry window, ordering statement, subscription health behavior, and authoritative read used for reconciliation. A route is “official” only when the provider documents it for the account and object scope in question; an API endpoint available somewhere else is not automatically a replacement.
For a concrete primary-source example, Shopify states that webhooks are not guaranteed to arrive in order and that delivery is not always guaranteed; it recommends reconciliation jobs. For HTTPS delivery, its current documentation says it retries a failed delivery eight times over four hours and notes automatic deletion after eight consecutive failures for Admin API-created subscriptions. Those are Shopify-specific facts, not promises about another provider. For repository webhooks, GitHub documents manual/API redelivery of deliveries from the past three days, without automatic redelivery; repository admin access is required. Neither policy generalizes.
| Evidence | Why it matters | Failure outcome |
|---|---|---|
| Topic and object scope match the approved signal | Prevents replacing a broader or narrower observation. | HOLD. |
| Stable delivery ID plus durable deduplication | Allows a retry to be recognized without deleting a real later change. | HOLD. |
| Provider’s ordering and retry terms | Sets the pending window; arrival order is not assumed to be business order. | HOLD. |
| Authoritative reconciliation read, with scope and cadence | Tests present state after delivery gaps or handler recovery. | KEEP_APPROVED_POLLING only if that existing current-state baseline is independently accepted; otherwise HOLD. |
| Subscription/handler health evidence | Finds a disabled subscription or a receiver outage. | HOLD until repaired and reconciled. |
Separate intake, materialization, and reconciliation
Verify the provider signature before accepting a delivery, save the raw delivery and its stable ID durably, acknowledge within the provider’s documented limit, and process it asynchronously. Deduplicate by the provider delivery ID—not by payload text. Two distinct changes can have identical visible fields, while one delivery can be retried. Keep a per-object “latest observed authoritative state” with the source timestamp/version where supplied. If version comparison is unavailable or ambiguous, do not invent an order from arrival time.
After the declared retry window plus an operational margin, reconcile each in-scope object from the authorized authoritative source. Reconciliation is a comparison, not an event replay: it can discover that the state is now different from the materialized state, but it cannot say how many short-lived changes occurred between reads. Quarantine a mismatch for review and emit neither a false “no change” nor an automatic business action.
| Arrival | Delivery ID | Offer version / state | Materialized result |
|---|---|---|---|
| 09:00 | d-2 | 3 / public-price-95 | version 3, price 95 |
| 09:01 | d-1 | 1 / public-price-100 | ignore older version; retain version 3 |
| 09:02 | d-2 | 3 / public-price-95 | ignore duplicate delivery ID |
| after pending window | authorized state read | 3 / public-price-95 | matches: eligible for current-state decision only |
These are synthetic records. The result handles a duplicate and out-of-order arrival, but does not prove no version 2 existed or establish a real delivery guarantee. Conflicting state for the same object/version, or conflicting content under one delivery ID, is HOLD in the fixture regardless of arrival order.
if any required acceptance decision is unknown: HOLD
elif every event must be retained: HOLD; redesign the evidence route
elif webhook coverage, authentication, or reconciliation is unproven:
KEEP_APPROVED_POLLING only if that current-state baseline is accepted; else HOLD
elif pending-window, IDs, versions, scope, or state checks fail: HOLD
else: USE_WEBHOOK_WITH_RECONCILIATION
Run a local, synthetic acceptance fixture
Download the offline webhook decision fixture. It uses Python 3.9+ standard library only; it makes no network calls, accepts no credentials, and all objects, events, timestamps, and states are synthetic.
python3 official-webhook-polling-reconciliation.py
The 15 built-in cases return 2 USE_WEBHOOK_WITH_RECONCILIATION, 1 KEEP_APPROVED_POLLING and 12 HOLD decisions. The fixture covers accepted coverage, duplicate delivery, out-of-order arrival, reconciliation mismatch, retry-window uncertainty, missing event ID, same-version conflict in both arrival orders, delivery-ID collision, and an every-event requirement. Its positive case earns USE_WEBHOOK_WITH_RECONCILIATION. The every-event case returns HOLD: redesign the evidence route or narrow the requirement. KEEP_APPROVED_POLLING only preserves an independently accepted current-state baseline when the webhook route is ineligible.
This is a single-source, single-tenant teaching model: object IDs and delivery IDs are assumed to be namespaced within the documented subscription, and integer versions have a proven per-object ordering. The flags are evidence supplied by a reviewer, not authentication or coverage checks performed by the script. It neither verifies a signature nor runs a retry timer, persists a queue, or repairs state. A real system must establish these controls separately; multi-tenant keys, deletions, pagination and schema changes need explicit handling.
Choose the operating path, including its economics
| Verdict | When it fits | Operating cost to compare | Next action |
|---|---|---|---|
| USE_WEBHOOK_WITH_RECONCILIATION | Current-state decision; coverage, identity, retry window and reconciliation scope are evidenced. | Receiver storage/operations plus a bounded reconciliation read, compared with approved poll work. | Run a limited, reversible parallel observation; retain the approved poll until the acceptance record closes. |
| KEEP_APPROVED_POLLING | The new route has not passed, but the current approved current-state baseline remains the temporary route. | Authorized request volume, scheduling, review labor, and missed-decision risk. | Keep the cadence; it is not proof of every-event completeness. |
| HOLD | Unknown scope, auth, ID, ordering, retry window, health, reconciliation result, or an every-event requirement that available routes cannot prove. | Do not substitute estimates for the missing evidence. | Ask the provider the named question; for every-event work, redesign/escalate an auditable route. |
Do not assume a webhook is cheaper simply because it reduces scheduled reads. Compare only measured or stated variables: approved request volume, retained-event or API terms, receiver operations, reconciliation work, and the cost of delayed human review. No IPHTML price, capacity, performance, demand, or savings claim is made here.
A narrow, safer rollout checklist
- Keep the existing authorized poll while recording a time-bounded parallel sample; do not count that sample as proof of every historical event.
- Test valid signature, invalid signature, duplicate ID, two different IDs with the same payload, reversed arrival, handler restart, retry-window expiry, and reconciliation mismatch.
- Log the provider documentation version, subscription scope, source-read scope, object identity, received time, source time/version, decision, and reviewer. Exclude credentials and sensitive targets.
- Switch only the named current-state decision after a reviewer accepts the record. Revisit it when the provider changes the topic, payload, retry policy, or reconciliation source.
For an authorized regional check that genuinely needs a residential route, evaluate the route separately through residential proxies. For a bounded architecture question, use contact; do not send credentials, signed payloads, or sensitive target details.
Related guides, not substitutes
Use public data-source selection to choose a lawful source in the first place, duplicate-request reduction to control repeated work, and retry budgets to bound request attempts. For a price-review cadence or a regional alert’s action rule, see promotion monitoring frequency and regional stock-alert policy. None establishes event completeness for this replacement decision.
Sources checked November 13, 2026: Shopify: About webhooks, Verify webhook deliveries, Troubleshoot webhooks, and GitHub: redelivering webhooks. Platform-specific delivery behavior must be rechecked against the actual provider’s current official documentation. Fixture timing and data are synthetic.