Card 06/ 07
Practice: Designing an API for Event Tickets
Browse events, hold seats for ten minutes, pay once and cancel; derive the endpoints and write the contract.
Designing an API end to end means deriving the endpoints from the requirements, deciding the cross-cutting rules, and reviewing the result. Design the API for a ticketing feature from these requirements, then run the checklist against your design.
- Anyone can browse upcoming events and see seat availability.
- A signed-in customer can hold up to six seats for ten minutes.
- The customer pays for a hold, exactly once, even if the app retries.
- A hold that is not paid within ten minutes expires and frees its seats.
- A customer can cancel a paid ticket up to 48 hours before the event.
Show a design
| Requirement | Endpoint | Decision |
|---|---|---|
| Browse events | GET /events, GET /events/{id}/seats | Public, paginated, cacheable with max-age and ETag |
| Hold seats | POST /events/{id}/holds → 201 | Body lists seat ids, at most six; 409 if a seat is taken; expiresAt in the response |
| Pay once | POST /holds/{id}/payment → 201 | Idempotency-Key required; 409 if the hold has expired |
| Expire holds | GET /holds/{id} shows status expired | The server expires holds on time; the client reads the status |
| Cancel | POST /tickets/{id}/cancellation → 201 | 409 with problem details within 48 hours of the event |
Cross-cutting. OAuth bearer tokens for holds, payments and tickets, each checked against the caller; browsing needs none. Problem details for every error. A rate limit on holds per customer, so one client cannot hold a whole venue. Path versioning under /v1.
The review. Paths are nouns, writes retry safely, every list is paginated, holds and tickets are checked against the caller, and the contract lists expired and cancelled as values of an open status enum. The OpenAPI document holds an example for each response.
← → move through sections and cards