Budi Santoso
@budi_santoso • 1 months ago
Check a draft API against seven questions (naming, idempotency, pagination, errors, versioning, auth) and get back a revised spec with every change marked.
consumersspec{{consumers}}{{spec}}consumers: Our React Native customer app, the salon owner dashboard (web), and two third-party booking aggregators calling with an API key.
spec:
```
POST /createBooking body: { salonId, serviceId, staffId, startTime, customerPhone }
GET /bookings?salonId= returns all bookings for the salon
POST /bookings/cancel body: { bookingId }
PUT /bookings/{id} body: { startTime } // reschedule
GET /slots?salonId=&date= returns free slots
Errors: { "success": false, "message": "..." } with HTTP 200
```POST /createBooking and POST /bookings/cancel are RPC-style. Use POST /bookings to create. Model cancel as a state change, POST /bookings/{id}/cancel, which is acceptable as an explicit action, or PATCH with status. Reschedule uses PUT with a partial body. PATCH is the honest method.POST /createBooking, retries, and the customer gets two bookings. Require an Idempotency-Key header on create and cancel, and store the key with the response for 24 hours. Cancel should also be naturally idempotent: cancelling an already-cancelled booking returns 200 with the same body.GET /bookings returning all bookings will get slower every month. Add cursor pagination, a date range filter and a status filter. /slots is bounded by date, so it's fine.code, for example 409 slot_unavailable, so the app can show "that slot was just taken" without parsing English./v1 now. Changing the startTime format or making a field required would force a v2.GET /bookings?salonId= would expose every customer's phone number to both aggregators. Salon owners see their salon's bookings, and customers see their own.startTime format. Decide now: ISO 8601 with offset (2026-10-02T15:30:00+05:30). Local times without an offset will cause bugs in partner integrations.``