# Review a REST API design before any client depends on it

> Check a draft API against seven questions (naming, idempotency, pagination, errors, versioning, auth) and get back a revised spec with every change marked.

- **Author:** [Budi Santoso (@budi_santoso)](https://promptabide.com/budi_santoso)
- **Tested on:** Claude · Opus 5.5
- **You fill in:** `consumers`, `spec`
- **Published:** 2026-07-31
- **Updated:** 2026-09-24
- **Tags:** `coding`, `web-development`, `code-review`, `product-management`
- **Keywords:** api design review prompt, rest api best practices checklist ai, review api endpoints before launch, idempotency and pagination api review, design api for mobile app and partners
- **Views:** 1627
- **Likes:** 36

**Best for:** Backend and full-stack developers about to ship an API that mobile apps or third parties will call and that will be hard to change later.

## Prompt

```
Review this API design before we build it. Once clients ship, mistakes here are expensive to undo.

Who calls it: {{consumers}}

Draft spec:
{{spec}}

Answer each question with a specific finding, or "fine":
1. Naming and methods: is anything an RPC call dressed up as REST? Are the HTTP methods right?
2. Idempotency: if a client retries each write after a timeout, what happens? Where do we need idempotency keys?
3. Lists: pagination, filtering and sorting on every list endpoint.
4. Errors: consistent, machine-readable, correct status codes, nothing internal leaked?
5. Versioning: how is it versioned, and what change would force a v2?
6. Auth: for each endpoint, who can read or modify whose data? Flag anything a partner key shouldn't reach.
7. The one decision here that will be hardest to change after clients ship.

Then give me the revised spec in the same notation I used, with each change marked // CHANGED and a few words on why. Keep anything that's fine as it is.
```

## Variables

- `{{consumers}}` — Who will call the API and how (e.g. React Native app, salon owner dashboard, two booking aggregators via API key)
- `{{spec}}` — Your draft endpoints and error format, in whatever notation you use (e.g. POST /createBooking, GET /bookings?salonId=, ...)

## Example input

````
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
```
````

## Output

*Produced by Claude · Opus 5.5.*

````
**1. Naming and methods.** `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.

**2. Idempotency.** This is the big one. A mobile client on a flaky 4G connection times out on `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.

**3. Lists.** `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.

**4. Errors.** HTTP 200 on failure breaks every HTTP client's retry and monitoring logic. Use real status codes, and a stable machine-readable `code`, for example `409 slot_unavailable`, so the app can show "that slot was just taken" without parsing English.

**5. Versioning.** There isn't any. Prefix with `/v1` now. Changing the `startTime` format or making a field required would force a v2.

**6. Auth.** Not specified. A partner API key must only see bookings it created. As drafted, `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.

**7. Hardest to change later:** the `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.

**Revised spec**
```
POST   /v1/bookings                  // CHANGED: resource-style; requires Idempotency-Key
       body: { salonId, serviceId, staffId, startTime, customerPhone }  // startTime ISO 8601 with offset
GET    /v1/bookings?salonId=&from=&to=&status=&cursor=&limit=  // CHANGED: paginated, filtered
       // partners: only bookings they created; phone masked
POST   /v1/bookings/{id}/cancel      // CHANGED: id in path; idempotent
PATCH  /v1/bookings/{id}             // CHANGED: partial update
       body: { startTime }
GET    /v1/slots?salonId=&date=&serviceId=  // CHANGED: slot length depends on service
Errors: HTTP 4xx/5xx + { "error": { "code": "slot_unavailable", "message": "..." } }  // CHANGED
```
````

## Why it works

The **seven fixed questions** stop the review drifting into style and cover the areas that hurt after launch: retries, unbounded lists, error semantics and data exposure. Asking **"what happens if a client retries after a timeout"** frames idempotency as a concrete failure (duplicate bookings), not an abstract principle. Question 6, **"flag anything a partner key shouldn't reach"**, caught the phone-number leak. Requiring the **revised spec in your own notation with // CHANGED markers** gives you something to paste into your design doc, not an essay.

## When not to use it

It isn't built for GraphQL schemas, gRPC services or event-driven designs, which have different failure modes, so adapt the questions before you use it. It also can't judge domain rules it doesn't know (can a booking be moved to another staff member?). If partners already integrate with the API, the answer is a migration plan, not a redesign.

---

Canonical HTML: https://promptabide.com/bides/review-rest-api-design-before-building
Agent guide: https://promptabide.com/llms.txt · https://promptabide.com/agent-instructions.md
Sitemap: https://promptabide.com/sitemap.xml
