Every developer has used a terrible API. Inconsistent naming, cryptic errors, pagination that makes no sense.
After reviewing 50+ production APIs (Stripe, GitHub, Twitch, and plenty of bad ones), I compiled the 7 most common design mistakes — and the exact patterns to fix them.
1. RPC-Style URLs Instead of Resources
❌ Bad:
POST /getUsers
POST /createUser
POST /deleteUser
✅ Good:
GET /users → List
POST /users → Create
GET /users/123 → Read
PATCH /users/123 → Update
DELETE /users/123 → Delete
HTTP methods are your verbs. URLs should be nouns. This is REST 101, but 40% of APIs I reviewed still get it wrong.
Exception: Actions that don not map to CRUD use a verb sub-resource:
POST /articles/42/publish
POST /payments/abc/refund
2. Mixing Naming Conventions
{
"firstName": "John",
"last_name": "Doe",
"Email-Address": "john@example.com"
}
Pick ONE convention:
{
"first_name": "John",
"last_name": "Doe",
"email_address": "john@example.com"
}
| Where | Convention | Example |
|---|---|---|
| URL paths | kebab-case, plural | /user-profiles |
| Query params | snake_case | ?sort_by=created_at |
| JSON fields | snake_case | first_name |
| Headers | Title-Case | X-Request-Id |
Stripe, GitHub, and Slack all use snake_case for JSON. Google uses camelCase. Both are fine — mixing is not.
3. Useless Error Messages
{ "error": "Bad request" }
vs.
{
"error": {
"code": "validation_error",
"message": "Email format is invalid",
"field": "email",
"docs": "https://api.example.com/docs/errors#validation_error"
}
}
Great APIs include: what failed, where it failed, a machine-readable code, and a link to docs. Stripe error responses are the gold standard here.
4. No Pagination (or Bad Pagination)
GET /users?page=500&limit=20
Offset pagination breaks when records are added/deleted between pages.
GET /users?limit=20&after=cursor_abc123
{
"data": [...],
"pagination": {
"has_more": true,
"next_cursor": "cursor_def456"
}
}
Cursor-based pagination is consistent and scales to millions of records.
5. No Versioning Strategy
Your API will change. Without versioning, every change risks breaking clients.
| Strategy | Example | Pros | Cons |
|---|---|---|---|
| URL path | /v1/users | Simple, explicit | URL changes |
| Header | Accept: application/vnd.api.v1+json | Clean URLs | Hidden |
| Query param | /users?version=1 | Easy to test | Messy |
Stripe uses URL versioning + date-based pinning. Each API key is pinned to a version. Most developer-friendly approach.
6. Authentication Afterthoughts
GET /users?api_key=sk_live_xxx
API keys in URLs end up in logs, browser history, and referrer headers.
GET /users
Authorization: Bearer sk_live_xxx
Auth checklist:
- Never pass secrets in URLs
- Use short-lived tokens + refresh flow
- Return 401 for missing/invalid auth, 403 for insufficient permissions
- Rate limit by API key, not by IP
7. Ignoring Idempotency
POST /payments { amount: 100 }
// network timeout... retry?
POST /payments { amount: 100 } // DOUBLE CHARGE
With idempotency keys:
POST /payments
Idempotency-Key: req_abc123
{ amount: 100 }
| Method | Idempotent | Safe to retry |
|---|---|---|
| GET | Yes | Yes |
| PUT | Yes | Yes |
| DELETE | Yes | Yes |
| POST | No | Need idempotency key |
| PATCH | Yes | Yes |
Stripe, Shopify, and Square all support idempotency keys on POST requests. If your API handles money or creates resources, you need this.
The Full Picture
These 7 mistakes cover the surface. A production API also needs:
- Rate limiting with clear headers (X-RateLimit-Remaining)
- Consistent filtering/sorting (?status=active&sort=-created_at)
- Bulk operations for performance
- Webhook design for async events
- GraphQL schema patterns
- Real-world examples from Stripe, GitHub, Twitch
I build tools, games, and resources for developers — all free or pay-what-you-want:
🛠️ 27+ Free Developer Tools — JSON formatter, UUID generator, password analyzer, and more. All browser-based, no signup.
🎮 27 Browser Games — Built with vanilla JS. Play instantly, no install.
📚 Developer Resources on Gumroad — AI prompt packs, automation playbooks, and productivity guides.
7 patterns free above. The guide covers 40+ patterns across REST, GraphQL, auth, versioning, pagination, error handling, rate limiting, and production deployment.
More Developer Resources
If you found this useful:
Also check out DonFlow — a free budget drift detector that shows where your money plan diverges from reality.
What is the worst API you have ever used? Drop a comment — I want to hear the horror stories.
📘 Free Resource
If you are building with a $0 budget, I wrote a playbook about what works, what doesn't, and how to think about the $0 phase.
📥 The $0 Developer Playbook — Free (PWYW)
Want the deep dive? The Extended Edition ($7) includes a 30-day launch calendar, 5 copy templates, platform comparison matrix, and revenue math calculator.
Top comments (0)