Overview
- Context
- A fictional clinic group, Meridian Clinics, receiving appointment requests from its website and a partner booking tool. All records are synthetic.
- Industry
- Healthcare operations (fictional)
- Engagement
- Technical demonstration built for this portfolio
- Status
- Interactive technical demonstration
My role
- Designed the pipeline and its failure handling
- Built the interactive simulation and its tests
Technical stack
- Webhooks
- Schema validation
- n8n or custom Node.js (target)
- CRM API
- Slack (team alerts)
The problem
Two sources send the same kinds of events in different shapes. Webhooks sometimes arrive twice, the CRM API sometimes times out, and a failed run has to be visible without exposing patient data in logs.
Requirements
- Validate every payload against a schema and reject invalid ones with a reason
- Process each event exactly once, even when a webhook is delivered twice
- Retry temporary errors with backoff and route permanent errors to a person
- Keep personal data out of logs
Solution architecture
Each lane is one workflow, in the order it runs.
Ingest
- Webhook received
- Secret check
- Schema validation
- Idempotency key check
Process
- Normalise fields
- AI step: classify request type
- Low confidence: human review
- Map to CRM fields
Deliver
- CRM upsert
- Retry with backoff on 5xx
- Team notification
- Reporting event
Errors
- Permanent error
- Dead-letter record
- Alert with reason
- Replay after fix
Implementation details
Idempotency
Each event carries an id. The pipeline records processed ids and acknowledges repeats without running side effects, so a double delivery never creates two records.
Retries with backoff
Timeouts and 5xx responses retry after increasing delays. A 4xx response is permanent and goes straight to the error path.
Structured, safe logging
Logs record event id, step, outcome and duration. Names, emails and phone numbers are masked before logging.
Human review
When the AI classification is below the confidence threshold, the event waits in a review queue instead of guessing.
Try the system
Safe Webhook Handling
Send a test event. Send it twice: it runs once.
View the synthetic payload
{
"id": "evt_7f3a01",
"source": "website",
"type": "appointment.requested",
"patient": {
"name": "Alex Fictional",
"email": "alex.fictional@example.com",
"phone": "555-010-2468"
},
"requestedDate": "2026-11-12",
"reason": "Routine dental cleaning and check-up"
}Run log
Event ids processed: 0 · runs: 0
Send an event to see each step logged. Personal details are masked in every log line.
Testing and quality assurance
- Unit tests cover validation, duplicate events, retry decisions and log masking
- Scenario buttons reproduce each failure on demand
What it demonstrates
This is a demonstration, so there are no client results to report. It shows the logic, safeguards and failure handling I build into production systems: validate every payload against a schema and reject invalid ones with a reason; process each event exactly once, even when a webhook is delivered twice; retry temporary errors with backoff and route permanent errors to a person.
Evidence
Working demo
Run the scenarios below; everything is simulated in your browser.
Lessons learned
- Decide what “the same event” means before building, then enforce it at the edge.
- Make failures loud and replayable; silent automation errors are the expensive ones.
Related services
Have integrations that fail silently?
Let’s make them reliable


