APIs & Backend Logic
Prompt API endpoints and backend logic with the contract spelled out: methods, schemas, validation, errors, and auth.
TL;DR
- Spell out the contract: method, path, request and response schemas, status codes, and errors.
- Require input validation and explicit error responses; backends fail at the edges.
- State the auth and authorization rules; the model will not guess your security model correctly.
Define The Contract
Method & PathState the verb and route, including params.
"PATCH /api/orders/:id"Request ShapeGive the body, query, and params as types.
body: { status: 'paid' | 'cancelled' }
params: { id: string }Response ShapeDefine the success body and status code.
200 -> { id, status, updatedAt }Validate Input
Schema ValidationValidate the body and params with your tool before using them.
"Validate with zod; 400 + field
errors on failure."Bounds & TypesState required fields, types, and allowed values.
"status must be one of the enum;
id must be a cuid."Never Trust InputTreat all client input as hostile until validated.
Parse, don't assume. Reject early.Errors & Status
Map The CasesList each failure and its status code.
404 not found, 401 unauth,
403 forbidden, 400 invalidNo LeaksReturn safe messages; never expose stack traces or internals.
"500 returns a generic message;
log the detail server-side."Consistent ShapeUse one structured error body across endpoints.
{ error: { code, message } }Auth & Safety
Who Can CallState authentication and the authorization rule.
"Auth required; only the order owner
or an admin may update."Side EffectsName writes, events, and idempotency needs.
"Idempotent: repeated PATCH to the
same status is a no-op."Rate & LimitsMention limits where abuse or cost is a concern.
"Rate-limit to 10/min per user."Tips
- Give the request and response shapes as types or schemas so the endpoint matches your API.
- Name the error cases and their status codes so failures are handled, not left to 500s.
Warnings
- Models write happy-path handlers that trust input; always require validation and error handling.
- Generated endpoints often omit authz checks and leak internals in error messages; demand both be handled.
In Practice
An endpoint request with the whole contract: schema validation, every error case and status, and the authorization rule. The result is a safe handler, not a trusting happy-path stub.
- The contract names the method, path, and request and response shapes.
- Validation is required with a concrete tool and a 400 response on failure.
- Each error case is mapped to a status code with no internal leakage.
- The authorization rule is stated so the endpoint is not left open.
Implement PATCH /api/orders/:id in our Next.js 15
route handler style (TypeScript).
Contract:
- params: { id: string (cuid) }
- body: { status: 'paid' | 'cancelled' }
- 200 -> { id, status, updatedAt }
Rules:
- validate params and body with zod; 400 + field errors
- auth required; only the order's owner or an admin may
update, else 403; if no session, 401
- 404 if the order does not exist
- idempotent: PATCH to the current status is a no-op 200
- unexpected errors: 500 with a generic message, log
the detail server-side (no stack traces to the client)
- error body shape: { error: { code, message } }
Use our prisma client `db` and `getSession()`.
Return the handler only.FAQ
The HTTP method and path, the request body and query/params with types, the success response shape and status, and every error case with its status code. A precise contract means the endpoint integrates with clients and tests without surprises.
Ask for it with your tool: 'validate the body with zod; return 400 with field errors on failure'. Specify which fields are required, their types, and bounds. Unvalidated input is the most common source of backend bugs and vulnerabilities.
Name the cases and their responses: not found returns 404, unauthorized returns 401, forbidden returns 403, validation returns 400 with details, and unexpected errors return 500 without leaking internals. Ask for consistent, structured error bodies.
State them explicitly. Say who may call the endpoint, how identity is established, and the authorization rule ('only the owner or an admin may update'). Models do not infer your security model and will happily write an open endpoint.