Common REST API Design Mistakes That Slow Down Backend Teams
Review REST API status codes, pagination, response contracts, versioning, and authentication conventions before adding consumers.
REST API design choices become harder to change once clients depend on them. Consistent status codes, pagination, field conventions, and authentication rules make the API easier to integrate and maintain.
Review these patterns before publishing an API contract or adding new consumers.
Common REST API Design Mistakes
1. Returning 200 for Errors
Returning application errors with a success status creates ambiguity for clients:
HTTP/1.1 200 OK
{
"success": false,
"error": "User not found"
}Every client that consumes this endpoint now has to check both the HTTP status code and a custom field inside the body. HTTP clients, proxies, logging tools, and API gateways all treat 200 as success. You are opting out of the entire HTTP middleware ecosystem.
Return 4xx for client errors and 5xx for server errors. The status code is not a suggestion.
2. No Consistent Error Response Shape
When errors look different on different endpoints, clients have to write defensive parsing code for each one. Sometimes it is {"error": "..."}. Sometimes it is {"message": "..."}. Sometimes it is {"errors": [...]}. Sometimes the status code is 400, sometimes 422, sometimes 500 for the same class of problem.
Define an error response schema and apply it everywhere. Document it. Make it the first thing in your API style guide.
3. Encoding Actions in URL Paths
POST /api/users/deactivate
POST /api/sendPasswordReset
GET /api/fetchUserOrders?userId=42
These are RPC-style paths. REST URLs identify resources. Actions are encoded in HTTP methods. When you need to express a state transition or command, model it as a resource:
POST /users/42/deactivations — create a deactivation record
POST /password-reset-requests — create a reset request
GET /users/42/orders — get a sub-resource
This is not pedantry. REST semantics exist because HTTP infrastructure — caches, proxies, gateways — makes decisions based on them.
4. Inconsistent Field Naming Conventions
userId in one endpoint, user_id in another, UserID in a third. This forces clients to maintain a per-endpoint naming map instead of a single deserialization rule.
Pick one convention — snake_case is conventional for JSON APIs — and enforce it in a linter or schema validator. Inconsistency at this level compounds every time a new field is added.
5. Returning Unbounded Collections
GET /users
Returning an unbounded collection can cause long responses, timeouts, or memory pressure as the dataset grows.
Collection endpoints with growing datasets need a default page size, a maximum page size, and documented pagination.
6. No Versioning Until It Is Too Late
Teams skip versioning because they expect the API to stay stable. It never does. Requirements change, field names turn out to be wrong, response shapes need restructuring. Without a version prefix, every change is potentially breaking.
Starting at /v1/ takes one minute. Retrofitting versioning after you have live clients takes a migration plan, client coordination, and months.
7. Using the Wrong HTTP Method for the Job
- Using
GETfor operations with side effects (triggering a job, sending a notification) - Using
POSTfor idempotent operations wherePUTis correct - Using
DELETEwith a request body to pass parameters
HTTP clients, caches, and proxies make assumptions based on method semantics. A GET request with side effects can be triggered by a browser prefetch. A POST where PUT belongs cannot be safely retried on network failure.
8. Inconsistent Nullability
A field that is sometimes present and sometimes absent is a nullable field in disguise. If an optional field can be missing from the response, document it as nullable. If it is always present, make it always present — never omit it from the response when its value is an empty string or zero.
Clients that parse your responses with strict deserialization will fail on fields that appear and disappear unexpectedly.
9. Floating Point for Money
Representing monetary amounts as float in JSON causes rounding errors that compound over time:
{ "amount": 10.10 }Use integers (cents/pence) or strings with fixed decimal precision. This is a correctness issue, not a style issue.
10. No Authentication on Sensitive Endpoints (or Inconsistent Auth)
Some endpoints require a Bearer token. Some use an API key. One legacy endpoint has no authentication at all because it was "internal." When authentication requirements are inconsistent, clients build workarounds and security teams find surprises in audits.
Define one primary authentication mechanism. Document which endpoints require which scopes or roles. Treat unauthenticated access to authenticated endpoints as a 401, never a silent permission error.
The Common Thread
Review the API from a client’s perspective. Write the OpenAPI specification, check what each error response tells the caller, and verify that the documentation is sufficient to use each endpoint.