Lesson 4 of 15
33. Design a Notification System

33.3 What are the doors?

3 min read+10 XP

Step 3: API and data model (10 minutes)

POST /v1/notifications body: { "idempotency_key": "order-881-shipped", "user_id": 42, "type": "order_shipped", "data": { "order_id": 881, "eta": "Friday" } } returns: 202 Accepted { "notification_id": "n_9f2..." } POST /v1/otp/send { "phone": "+91...", "purpose": "login" } → 202 { "request_id": "otp_77" } POST /v1/otp/verify { "phone": "+91...", "code": "482913" } → 200 { "ok": true } | 400 / 429 GET /v1/notifications/{id} → { "status": "delivered", "channel": "push", ... } PUT /v1/users/{id}/preferences → opt-ins, quiet hours, language POST /v1/campaigns → template, audience, schedule (marketing only)

202 Accepted, not 200: the API queues the work and returns; delivery happens asynchronously (Chapter 22). The caller passes an idempotency key so a retried API call doesn't create a second notification (Chapter 24).

The OTP API is separate on purpose: callers never see the code. The notification system generates, stores (hashed) and verifies it, so the code never sits in another team's logs.