Getting ChatGPT to Write Accurate Webhook Handlers Without Missing Edge Cases
You paste a quick prompt into ChatGPT asking for a webhook handler, and you get something that looks reasonable β a route, a JSON parse, a 200 response. Then you deploy it, Stripe sends a retry at 3am, and you process the same payment twice. The code wasn't wrong; it just wasn't complete.
Webhook handlers are deceptively simple on the surface. The edge cases live underneath: signature validation, idempotency keys, partial delivery, provider-specific retry behavior, and the silent difference between a 200 and a 500 that your provider treats as a failure. ChatGPT will miss most of these unless you tell it exactly what you need.
What You'll Learn
- Why ChatGPT's default webhook output skips critical safety mechanisms
- How to structure prompts that produce signature-verified, idempotent handlers
- How to ask for correct retry behavior and error response semantics
- Common patterns that look right but fail in production
- A reusable prompt template you can adapt for any webhook provider
Prerequisites
This guide assumes you're working with a backend language (examples use Python/FastAPI and Node.js/Express). You should have a basic understanding of HTTP, JSON, and at least one webhook provider's documentation β Stripe, GitHub, Twilio, or similar. No ML or AI background needed.
The Default Prompt Problem
When most developers ask ChatGPT for a webhook handler, they write something like:
Write a Stripe webhook handler in FastAPI.
or:
Create an Express webhook endpoint for GitHub.
The model responds with something like:
@app.post("/webhook")
async def webhook(payload: dict):
print(payload)
return {"status": "ok"}
Technically valid.
Completely unsafe.
Missing:
- Signature verification
- Replay protection
- Idempotency handling
- Retry awareness
- Event validation
- Logging
- Monitoring
- Dead-letter handling
The problem is that ChatGPT optimizes for satisfying the request, not anticipating production requirements you didn't mention.
Why Webhooks Are Harder Than They Look
Most API requests originate from your application.
Webhooks originate from someone else's.
That changes everything.
Your application doesn't control:
- Delivery timing
- Retry frequency
- Request ordering
- Network reliability
- Duplicate deliveries
A webhook system must assume:
Events arrive twice
Events arrive late
Events arrive out of order
Events occasionally fail
Most generated examples ignore these realities.
The First Prompt Improvement
Instead of:
Write a webhook handler.
use:
Write a production-ready webhook handler.
Requirements:
- Signature verification
- Idempotency protection
- Safe retry handling
- Structured logging
- Event validation
Explain every safety mechanism.
This immediately improves output quality.
The model starts reasoning beyond simple request handling.
Signature Verification Is Non-Negotiable
One of the most common AI-generated mistakes:
payload = await request.json()
and immediately processing it.
Dangerous.
Without signature verification:
Anyone can send requests to the endpoint.
Example:
curl https://api.example.com/webhook
could trigger business logic.
Most providers supply:
Webhook Secret
Signature Header
Timestamp
Examples:
| Provider | Header |
|---|---|
| Stripe | Stripe-Signature |
| GitHub | X-Hub-Signature-256 |
| Twilio | X-Twilio-Signature |
| Shopify | X-Shopify-Hmac-SHA256 |
Always tell ChatGPT:
Validate provider signatures before processing payloads.
Reject invalid requests.
If you don't, verification is frequently omitted.
The Raw Body Trap
This causes production outages constantly.
Many frameworks parse JSON automatically:
payload = await request.json()
or:
req.body
Some providers calculate signatures using:
Raw Request Body
not parsed JSON.
Verification fails if the payload changes even slightly.
Prompt explicitly:
Use the raw request body for signature validation.
Only parse JSON after verification succeeds.
This prevents one of the most common webhook implementation mistakes.
Idempotency: The Missing Safety Layer
Webhook providers retry.
Often aggressively.
Example:
Event delivered
Timeout occurs
Provider retries
Your application may process:
Same payment
Same order
Same subscription
multiple times.
Without protection:
Customer charged twice
Email sent twice
Order fulfilled twice
This is where many AI-generated handlers fail.
Bad pattern:
process_payment(event)
every time the webhook arrives.
Better pattern:
if event_id already processed:
return success
process_event()
store_event_id()
Prompt ChatGPT with:
Prevent duplicate processing using provider event IDs.
This dramatically improves output.
Event Ordering Problems
Developers often assume:
Event A
Event B
Event C
arrive in that order.
Many providers explicitly do not guarantee ordering.
Example:
subscription.updated
arrives before:
subscription.created
because of network delays.
If your logic depends on sequence, problems emerge quickly.
Prompt:
Assume webhook events may arrive out of order.
Design handlers accordingly.
This often pushes the model toward:
- State reconciliation
- Database lookups
- Defensive processing
instead of naive sequencing.
The 200 vs 500 Problem
Webhook providers interpret responses differently.
A common mistake:
try:
process_event()
except:
pass
return 200
Looks harmless.
Actually dangerous.
You just acknowledged successful processing even though work failed.
The provider stops retrying.
The event is lost forever.
The opposite mistake:
return 500
for permanent validation failures.
Now the provider retries forever.
Correct behavior depends on the error type.
Return 200 When
- Event already processed
- Event intentionally ignored
- Processing completed successfully
Return 400 When
- Invalid signature
- Malformed payload
- Unsupported schema
Return 500 When
- Database unavailable
- Temporary infrastructure failure
- Retry is appropriate
Prompt:
Differentiate permanent failures from transient failures.
Return appropriate HTTP status codes.
Async Processing Is Usually Better
Another common AI-generated pattern:
verify_signature()
send_email()
update_database()
call_external_api()
generate_invoice()
return 200
This creates long request times.
Webhook providers often have strict timeout limits.
Better:
verify_signature()
enqueue_job()
return 200
Then:
Worker processes event asynchronously
Prompt:
Acknowledge quickly.
Move heavy processing to a background queue.
This produces much more resilient architectures.
Logging Requirements Most Prompts Miss
Basic examples often log:
print(payload)
which isn't useful.
Production logs should capture:
- Event ID
- Event Type
- Timestamp
- Processing Outcome
- Error Details
Example:
event_id=evt_123
event_type=payment_succeeded
status=processed
Prompt:
Add structured logging for observability.
This significantly improves troubleshooting.
Validate Event Types Explicitly
Many webhook handlers trust:
event["type"]
without validation.
Example:
if event["type"]:
process()
Better:
SUPPORTED_EVENTS = {
"payment_succeeded",
"payment_failed",
"subscription_updated"
}
Reject everything else.
Prompt:
Use explicit allowlists for event types.
This reduces accidental behavior changes when providers introduce new event categories.
Ask ChatGPT to Threat Model the Handler
One of the most valuable prompts:
Before writing code:
List all webhook-specific risks:
- Replay attacks
- Duplicate delivery
- Invalid signatures
- Out-of-order events
- Provider retries
- Partial failures
Then design mitigations.
This forces deeper reasoning before implementation.
Stripe-Specific Prompt Additions
For Stripe:
Use Stripe-Signature verification.
Store Stripe event IDs.
Handle duplicate delivery safely.
Assume retries occur.
Use official Stripe SDK validation.
This produces far better results than generic webhook requests.
GitHub-Specific Prompt Additions
For GitHub:
Validate X-Hub-Signature-256.
Verify repository ownership.
Handle ping events separately.
Support delivery retries.
Provider-specific context matters.
The Self-Audit Prompt
After receiving generated code, ask:
Review your webhook handler.
Identify:
1. Duplicate processing risks
2. Replay attack risks
3. Signature verification weaknesses
4. Timeout risks
5. Retry handling flaws
6. Event-ordering assumptions
Suggest improvements.
This often uncovers missing protections immediately.
Common AI-Generated Webhook Bugs
Missing Signature Validation
Most dangerous.
Parsing JSON Before Verification
Common framework issue.
No Idempotency Protection
Creates duplicate actions.
Blocking Processing Inside Request
Causes timeouts.
Assuming Event Order
Breaks under real-world delivery.
Incorrect HTTP Responses
Creates lost events or infinite retries.
Logging Too Little
Makes debugging impossible.
A Production-Ready Prompt Template
Use this whenever generating webhook code:
Act as a senior backend engineer.
Write a production-ready webhook handler.
Requirements:
- Signature verification
- Raw body validation
- Idempotency protection
- Event-type allowlist
- Structured logging
- Safe retry handling
- Correct HTTP status codes
- Asynchronous processing
- Replay protection
Assume:
- Duplicate delivery
- Out-of-order delivery
- Provider retries
- Temporary infrastructure failures
Before generating code:
1. Identify risks
2. Explain mitigation strategy
After generating code:
1. Audit for edge cases
2. Explain failure handling
3. Explain retry behavior
This consistently produces safer results than asking for a webhook route alone.
Testing Before Production
Never deploy a generated webhook handler without testing:
Duplicate Deliveries
Send the same event twice.
Invalid Signatures
Verify rejection behavior.
Provider Retries
Simulate timeouts.
Out-of-Order Events
Replay events in unexpected sequences.
Database Failures
Confirm retry semantics.
Webhook systems fail most often during unusual conditions rather than happy-path execution.
Final Thoughts
Webhook handlers look simple because the happy path is simple. Receive JSON, process it, return a response. The real complexity comes from everything that happens outside the happy path: duplicate deliveries, retries, signature validation, out-of-order events, timeouts, and partial failures. These are precisely the scenarios that basic AI-generated examples tend to ignore.
The solution is not to stop using ChatGPT. It's to stop asking for webhook handlers as if they're simple routes. Explicitly require signature verification, idempotency, retry handling, event validation, and failure analysis in your prompts. Then ask the model to audit its own output before you trust it.
With the right prompting strategy, ChatGPT becomes much better at generating production-ready webhook infrastructure. Without that guidance, it will usually give you code that works perfectlyβright up until the first retry storm arrives in production.
Frequently Asked Questions
Why does ChatGPT skip signature verification when generating webhook handlers?
ChatGPT generates the most common, minimal implementation by default and signature verification is often omitted from tutorial examples it was trained on. You need to explicitly name the provider and ask for HMAC verification with the raw request body to get it included.
How do I make ChatGPT generate idempotent webhook handlers?
Tell ChatGPT the idempotency field your provider sends (like Stripe's Stripe-Signature and idempotency key headers), and ask it to check a processed-events store before acting. Without that explicit instruction, it will process every delivery unconditionally.
What HTTP status codes should a webhook endpoint return to avoid retry storms?
Return 200 for successful receipt, 400 for permanently invalid payloads you never want retried, and 500 only for transient errors where a retry is safe. Returning 500 for all errors causes providers like Stripe and GitHub to retry aggressively, which can trigger duplicate processing.
Can ChatGPT handle webhook handlers for multiple providers at once?
You can ask ChatGPT to generate a multi-provider handler, but you'll get better results generating one provider at a time and then asking it to compose them. Multi-provider prompts tend to blur provider-specific signature schemes and header names.
How should I test ChatGPT-generated webhook handlers for edge cases before deploying?
Ask ChatGPT to also generate a test suite covering duplicate event IDs, invalid signatures, missing required fields, and out-of-order delivery. Then run those tests against your local handler using tools like the Stripe CLI or a mock HTTP server before any production deployment.
π€ Share this article
Sign in to saveRelated Articles
Comments (0)
No comments yet. Be the first!