Replay Webhook Deliveries from the Delivery Log (Safely)
Replay Webhook Deliveries Safely
Replay is a powerful recovery tool when used with idempotent consumers. This guide explains when to replay, when not to, and an exact safety checklist so replays don’t cause duplicate side effects.
You’ll implement safe replay workflows and validate idempotency in your Laravel consumer before you press “replay”.
When replay is the right tool
Replay is for temporary outages and resolved downstream failures — not for contract bugs.
Endpoint outage fixed
Replay after your endpoint is fully healthy.
Temporary 5xx / timeouts resolved
If the consumer was failing due to transient errors, replay once the root cause is gone.
Downstream dependency recovered
Replay after dependent services (DB, third-party APIs) are back online.
Mini incident: A 5xx from the consumer caused retries; replay after the fix delivered the missing invoice without duplicate charges.
When replay is the wrong tool
Replaying will repeat the same delivery — don’t replay if the payload or template is the root cause.
Permanent 4xx due to contract mismatch
4xx means the consumer disagrees with the contract; fix the contract, then replay.
Bad payload/template bug (replay repeats the bug)
If the payload itself is malformed, replaying will repeat the error.
Common gotcha: Replaying immediately after a fix without verifying idempotency — always confirm the consumer dedupe before replay.
Replay safety checklist
Follow this checklist before replaying any run.
Verify consumer idempotency (dedupe store)
- Confirm an
inboxor unique constraint prevents duplicate side effects.
Confirm signature verification is working
- Verify
X-SP-SignatureandX-SP-Timestampare validated.
Ensure endpoint returns 2xx quickly (ack fast)
- Ensure the endpoint responds <1s for the acknowledgment path.
Micro checklist:
- Inbox table or unique constraint verified
- Signature verification enabled
- Side effects are idempotent or safely retryable
Practical replay workflow
- Find the failing run in Message Log.
- Inspect the last attempt — confirm response body, status, and headers.
- Fix the root cause in your consumer.
- Replay the run and verify you receive a 2xx.
- Confirm side effects executed once.
Find run → inspect last attempt → fix root cause
Check the last attempt’s response body and headers for clues (auth, validation errors, timeouts).
Replay → verify 2xx outcome
Confirm the replayed attempt returns 2xx and the run marks success.
Confirm side effects executed once
Use your app logs and correlation_id / dedupe store to ensure the side effect ran a single time.
Idempotency patterns for webhook consumers
Inbox table + unique constraint
| |
Dedupe key strategy (request ID / signature / body hash)
Prefer a stable run/event ID over body hash when payloads may vary between attempts.
Common gotcha: Using body hash alone for dedupe when bodies can differ slightly between attempts.
Signature verification reminder (raw body)
| |
Test steps
- Force a failure (return 500)
- Temporarily make your webhook endpoint return 500.
- Trigger an event.
- Confirm in Message Log the attempt is failed and retries are scheduled.
- Fix the endpoint (return 204/200 quickly)
- Replay from Delivery Log
Expected: replay attempt returns 2xx, run shows success, and your consumer processes once (dedupe prevents duplicates).
Trigger a webhook via the Sample Project, intentionally fail your endpoint, then replay after fixing and confirm success in Message Log.
Common failure modes
- Replaying before fixing the root cause (replay fails again).
- No idempotency in consumer → replay causes duplicate side effects.
- Consumer does work inline, times out → still fails and continues retries.
- Treating 4xx as replayable (usually a contract bug).
- Signature verification disabled in prod (replay appears to work but is insecure).
- Using body hash alone for dedupe when bodies can differ.
Internal links + CTA
SendPromptly webhook semantics: each endpoint has its own delivery run, success is HTTP 2xx, failures retry with exponential backoff; signature headers exist and should be validated.
- Delivery logs & debugging overview
- Webhook delivery rules + signature headers
- Find failed runs quickly
- Correlation IDs and tracing workflow
Key takeaways
- Replay only after the root cause is fixed and idempotency verified.
- Use an inbox table or unique constraint to dedupe.
- Confirm signature verification and fast 2xx acknowledgements before replay.
Replay is safe when your consumer is idempotent—verify in Message Log, then confirm side effects once.