Reliable webhook receiver: signatures, idempotency, queue and retries
Build a webhook endpoint that verifies the HMAC signature, responds fast, queues the work, ignores duplicates, and retries with backoff and a dead-letter queue. Designed for ChatGPT, Claude, Gemini and Microsoft Copilot. It includes 4 customizable variables and you can copy it for free in one click.
Advanced · Code · Pending editorial review
Prompt
Act as a backend engineer experienced in integrations and distributed systems.
I need to receive webhooks reliably:
- Provider and how it signs requests: {{provider}}
- Events I care about and what I do with each: {{events}}
- Stack: {{stack}}
- Available queue system: {{queue}}
Deliverables:
1. A text diagram of the flow: receive, verify, persist, enqueue, process, retry and dead-letter.
2. The receiving endpoint:
- Read the raw body before parsing and verify the HMAC signature with a constant-time comparison.
- Reject requests whose timestamp is outside a short window to prevent replay attacks.
- Store the event and return 2xx within milliseconds; no heavy logic in the request.
3. Idempotency: an events table with the provider's event id as a unique key, states (received, processing, done, failed) and what to do when the same event arrives twice.
4. Worker: processing with exponential backoff and jitter, a maximum attempt count, a distinction between transient and permanent errors, and a dead-letter queue with a way to replay it.
5. Ordering: how to handle out-of-order events (for example by checking the resource version or timestamp, or re-fetching from the provider's API).
6. Logging and alerting: what to log without storing sensitive data and which metrics to watch.
7. Tests: valid and invalid signature, duplicate event, stale timestamp, transient failure that recovers and permanent failure that lands in the dead-letter queue.
8. How to test locally (tunnel or event forwarding) without exposing the secret.
Constraints:
- Do not guess the provider's exact signature format or header names: if I do not give them, mark them as [FILL IN] and tell me where to look in their docs.
- Read the secret from environment variables or a secrets manager, never from code.
- If key information is missing, ask me before writing code.How to use it
- Copy the signature header and algorithm from your provider's documentation.
- List the events you need and the business action for each.
- Test locally with forwarded events and force failures on purpose to watch the retries.
- Monitor the dead-letter queue after deploying.
Usage example
Provider: payment gateway signing with HMAC-SHA256 in a header · Events: payment succeeded, refund · Stack: Python with FastAPI · Queue: Celery with Redis.
Sample output
1. Flow
Gateway → POST /webhooks/payments → verify signature + timestamp → INSERT event (unique)
→ commit → 200 → Celery: process → retries with backoff → dead-letter
2. Receiving endpoint
@router.post("/webhooks/payments")
async def receive(request: Request, db: AsyncSession = Depends(get_db)) -> dict:
raw = await request.body() # raw body, before parsing
ts = request.headers.get("[FILL IN: timestamp header]", "")
sig = request.headers.get("[FILL IN: signature header]", "")
if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
raise HTTPException(400, "missing or stale timestamp")
# Signed message format per the provider's docs: [FILL IN]
expected = hmac.new(settings.webhook_secret.encode(),
f"{ts}.".encode() + raw, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig): # constant-time comparison
raise HTTPException(400, "invalid signature")
event = json.loads(raw)
stmt = (insert(WebhookEvent)
.values(provider_event_id=event["id"], type=event["type"],
payload=event, status="received")
.on_conflict_do_nothing(index_elements=["provider_event_id"])
.returning(WebhookEvent.id))
new_id = (await db.execute(stmt)).scalar_one_or_none()
await db.commit()
if new_id is not None: # duplicate → not enqueued again
process_event.delay(new_id)
return {"ok": True}
We enqueue after the commit so the worker never reads an event that does not exist yet…
Key facts
- Category
- Programming & development · APIs
- Output type
- Code
- Level
- Advanced
- Designed for
- ChatGPT, Claude, Gemini and Microsoft Copilot
- Verified in
- Pending editorial verification
- Variables
- Provider and signature, Events and actions, Stack and Queue system
- Language
- English
- Price
- Free, no sign-up
- Updated
- Nov 7, 2026
Frequently asked questions
Why return 2xx before processing the event?
Many providers treat slow webhooks as failed and resend them, which causes duplicates and extra load. Storing and queuing lets you answer immediately and process calmly.
Why verify the signature against the raw body?
The signature is computed over the exact bytes the provider sent. If you parse and re-serialize the JSON, whitespace or key order changes and verification fails.
What is this prompt for?
Build a webhook endpoint that verifies the HMAC signature, responds fast, queues the work, ignores duplicates, and retries with backoff and a dead-letter queue.
Which AI tools does it work with?
It is designed for ChatGPT, Claude, Gemini and Microsoft Copilot. We have not verified it in these tools yet, so results may vary between them.
How do I customize the prompt?
Click “Customize” and fill in the variables (Provider and signature, Events and actions, Stack and Queue system). The text updates instantly and you can then copy it in one click. Values are stored only in your browser.
Do I need experience to use it?
It is advanced: it is meant for people with experience in the topic who can evaluate and adjust the result.
Is this prompt free?
Yes. Every HomeCasa Prompts prompt is free, with no sign-up or subscription. You can also use them in professional projects.
Can I trust the AI output?
Treat it as a high-quality draft: always check data, figures and important claims before publishing or making decisions.