Evidence · 02
How do you design APIs?
37 routes on ConfirmHai, grouped by resource rather than by feature ticket — so a new engineer (or an AI coding tool) can find where a change belongs without reading the whole codebase.
Resource modeling
Illustrative resource grouping
| Resource group | Covers |
|---|---|
| Owners & auth | Registration, OTP issue/verify, JWT session |
| Listings & confidence | Listing CRUD, score refresh, freshness nudges |
| Matching | Roommate compatibility quiz and results |
| Unlocks & payments | Paid contact unlock, payment_ref idempotency |
| WhatsApp webhooks | Inbound Meta Cloud API events, signature verification |
Auth flow
JWT issuance gated behind a rate-limited OTP
Client
POST /owners/register
Server
OTP issued
- bcrypt-hashed
- TTL + attempt-capped
Client
POST /owners/verify-otp
Server
JWT issued
- Denylist-checked on every request
Webhook design
Never trust an inbound webhook by default
Every WhatsApp/Meta Cloud API webhook is signature-verified before its payload is processed — the endpoint rejects unsigned or forged requests before they reach any business logic, rather than validating after the fact.
API design decision
Idempotency keys on anything that trades money or unlocks a resource
The payment_ref pattern generalizes: any mutating endpoint with an external side effect (payment, unlock, notification) needs to be safe against being called twice with the same intent — because it will be, whether from a retried webhook, a flaky client, or an impatient double-tap. That safety has to live at the API layer, not be hoped for at the UI layer.