Designing an API from scratch: what should I decide first?
Changing a line at design time is far cheaper than changing a field after launch. Keep the uncertainty while nobody depends on the API yet.
How to do it
Turn the requirement into entities and states
Paste the requirement and main use cases into 'Turn a requirement into a data model' without asking for code. Ask for entities, relationships and cardinality, the state machine of the core object, fields likely to change within six months, and three questions you must take to the product owner. The entities and transitions decide which resources exist and which actions should not be exposed directly.
Stress-test the design before anyone implements it
Give the resources, paths, request and response examples, pagination, and error code draft to 'Stress-test an API design'. It should list five things most likely to break during implementation, redundant and missing fields, backward-compatible fixes, and a simpler alternative if one exists. Changing it now means editing a document; changing it after callers exist means scheduling work.
Write the failure paths down
Once the error codes and retry rules take shape, give the relevant code to 'Review error handling'. Look only at failure paths: swallowed exceptions, error messages missing the key id, unsafe duplicate writes, and places that should fail but keep going. The error codes and retry semantics it produces belong in the API docs, because callers will depend on them.
Lock the contract with tests
Give the implementation and tests to 'Find the gaps in your tests'. Fill in the edges: empty lists, oversized fields, duplicate submissions, missing permissions, upstream timeouts. Each case needs an input, an expected result, and why it is easy to miss. Contract tests should assert status codes and response shape, not internals.
Split the work only after the contract is frozen
Finally, give the frozen contract and team size to 'Split the Work So It Can Run in Parallel'. Fix the ordering constraints first, cut the rest into independently deliverable units, and mark dependency direction and the shared files most likely to collide. Frontend can build against mocks from the contract instead of waiting for the backend.
Prompts used
FAQ
Should an API have a version number from day one?
Leave room for one, but you do not need /v2 on day one. Stabilize resource names, error codes, and pagination first. When a breaking change is genuinely unavoidable, versioning is the cheapest fork. Adding a version layer for imagined changes usually just means maintaining duplicate routes.
The API isn't implemented yet. Can AI review the design?
Yes, and that is the cheapest time to change it. Give it request and response examples, error codes, and caller scenarios so its critique has evidence. A one-line 'design a user API' prompt gets you generic advice.
Are more granular error codes always better?
No. What callers actually need to distinguish is whether they can retry, whether to show the user a message, and whether it is a permission problem. Grouping codes along those three questions is easier to use correctly than dozens of bespoke codes.