Welcome to API Hell: The Seven Deadly Sins (and a Few More) of Bad API Design

Welcome to API Hell: The Seven Deadly Sins (and a Few More) of Bad API Design
Photo by Aaqiib Rasool / Unsplash

Building an API is a craft — part engineering, part empathy. It’s not just about making data accessible, but making it predictable, secure, and pleasant to use. Yet, so many developers unknowingly create what can only be described as API Hell.

If your API commits any of the following sins, then yes, you’re probably going to need divine intervention — or at least a good rewrite.


1. Returning 200 OK for Everything — Even Errors

Imagine someone telling you “Everything’s fine” while the building burns behind them.
That’s what happens when an API returns 200 OK for failed operations.

HTTP status codes exist for a reason. They communicate meaning before the user even reads the body. Using the right one makes debugging and client logic easier.

  • 400 Bad Request → Input validation failed.
  • 401 Unauthorized → Token missing or invalid.
  • 403 Forbidden → User doesn’t have permission.
  • 404 Not Found → Resource doesn’t exist.
  • 409 Conflict → Duplicate or conflicting data.
  • 500 Internal Server Error → Something broke on your side.

Returning 200 for everything doesn’t make your API “simpler.” It makes it untrustworthy.


2. RPC-style Endpoints Like /getUser or /createUser

REST is not an action-based protocol — it’s resource-oriented.
Your API shouldn’t sound like a series of functions. It should sound like a representation of entities.

Bad:

/getUser
/createUser
/deleteUser

Good:

GET /users/{id}
POST /users
DELETE /users/{id}

When you use HTTP methods correctly, you gain consistency, cacheability, and clarity for free.


3. Returning Passwords or Tokens in Responses

This one isn’t just bad — it’s dangerous.
If your API ever returns passwords, hashed or not, you’re opening the gates of hell. Even returning tokens on normal endpoints (outside of authentication) is a red flag.

Keep sensitive data on the server.
Return tokens only on login and only once. Store them securely and send them using the Authorization header.

Security 101: If you don’t need it in the response, don’t send it.


4. Inconsistent Naming: user_id, UserId, and idUser in the Same Response

Inconsistent naming makes APIs look like Frankenstein’s monster — stitched together by multiple developers with no shared convention.

Choose one style and stick with it:

  • For JSON: snake_case (user_id) is common.
  • For JavaScript-heavy projects: camelCase (userId) may be preferred.

What matters most is consistency across endpoints.
Clients shouldn’t need a translator to figure out your field names.


5. Returning null Instead of Empty Arrays

If an endpoint returns a list, always return an array, even if it’s empty.

Bad:

{ "items": null }

Good:

{ "items": [] }

Clients expect consistent types. Returning null breaks loops, validations, and sometimes entire UI components. Remember: Consistency is more important than cleverness.


6. Vague Error Responses like { "error": "Something went wrong" }

This one is the equivalent of saying “Oops.” — it helps no one.

A well-designed error should tell you:

  • What went wrong
  • Why it went wrong
  • (Optionally) How to fix it

Example:

{
  "error": {
    "code": "INVALID_EMAIL",
    "message": "The provided email address is not valid."
  }
}

You can also include HTTP status, timestamp, and request ID for traceability.
Clarity in error handling is what separates professional APIs from hobby projects.


7. Confusing Endpoints Like /user and /users/{id}

Ambiguity is poison for API design.
If GET /user means “get current logged-in user,” it’s better expressed as GET /me.

Let /users/{id} represent a specific user by ID.
Clear endpoint semantics mean no one has to guess what a route does — and that’s a huge win for maintainability.


8. Putting Tokens in Query Strings (GET /users?token=abc123)

Never, ever do this. Query strings are logged, cached, and stored in browser history.
Tokens belong in the Authorization header, not in URLs.

Correct way:

Authorization: Bearer abc123

Keep your authentication mechanism out of sight and secure. Anything else is a liability.


9. Ignoring Versioning

An API without versioning is like a live wire — touch it once, and something breaks.
Even if your API is new, plan for versioning early.

Common options:

  • Path-based: /v1/users
  • Header-based: Accept: application/vnd.example.v1+json

Versioning gives you freedom to evolve without breaking existing clients.


10. Overloading a Single Endpoint for Multiple Purposes

Some developers try to get clever:

POST /users?action=update

This breaks REST principles. Each endpoint should have one clear purpose.
If you need multiple actions, use multiple routes or a separate command-style API.

Clean separation of responsibility makes maintenance much easier.


11. Inconsistent Pagination and Filtering

Returning different pagination formats across endpoints is another subtle form of hell.
Adopt a uniform convention — for instance:

{
  "data": [ ... ],
  "meta": {
    "page": 2,
    "per_page": 20,
    "total": 95
  }
}

Same structure, every time. Clients will thank you.


12. Missing or Misleading Documentation

The worst sin of all: no documentation.
Even a perfectly structured API becomes useless without guidance.

At the very least, provide:

  • OpenAPI/Swagger schema
  • Examples for every endpoint
  • Error codes and meanings
  • Authentication guide

An undocumented API is like a maze without a map — people will just leave.


13. Silent Failures

Some APIs quietly drop invalid parameters or ignore missing fields without warning.
This might seem “forgiving,” but it actually makes debugging impossible.

Always respond with explicit validation errors. Transparency builds trust.


14. Leaking Internal Details

Returning stack traces, SQL errors, or internal messages is another common sin.
Never expose your system internals in API responses.
A production API should show user-friendly error messages and log detailed errors privately.


The Road to Redemption

Building a great API isn’t about perfection — it’s about consistency, clarity, and empathy for the people using it.

Follow these golden rules:

  • Use HTTP semantics correctly
  • Keep naming and structures consistent
  • Secure your data and endpoints
  • Return predictable types
  • Write clean, structured error responses
  • Document everything

Because at the end of the day, good APIs feel invisible — they just work.


In short:
If your API sins look like /getUser, leaks tokens, and says “200 OK” when the world is on fire… congratulations, you’ve reached API Hell.

But the good news? Redemption is only a refactor away.

Support Us

Share to Friends