A well-designed REST API is a product in itself. Developers who consume your API form opinions about your entire engineering team based on how the endpoints behave. After building APIs for CRM systems, mobile apps, and third-party integrations, we have distilled our approach into concrete, actionable patterns.
This guide covers the practices that matter most in production ÔÇö not academic REST purity, but practical decisions that reduce bugs and support calls.
URL Structure: Be Predictable
Your URLs should be guessable. A developer who knows one endpoint should be able to guess the rest.
- Use plural nouns:
/api/v1/customers, not/api/v1/customer - Nest related resources one level deep:
/api/v1/customers/42/invoices - Avoid deep nesting:
/api/v1/invoices?customer_id=42is better than three levels deep - Use hyphens for multi-word resources:
/api/v1/purchase-orders - Never put verbs in URLs:
POST /api/v1/invoices, not/api/v1/create-invoice
HTTP Methods and Status Codes
Use HTTP methods and status codes correctly ÔÇö they are the vocabulary of your API.
- GET ÔÇö retrieve resources. Always safe and idempotent. Return
200with data or404if not found - POST ÔÇö create new resources. Return
201with the created resource and aLocationheader - PUT ÔÇö full replacement of a resource. Return
200with updated resource - PATCH ÔÇö partial update. Send only changed fields. Return
200 - DELETE ÔÇö remove a resource. Return
204with no body
Common status codes you should use consistently:
400ÔÇö malformed request (bad JSON, missing required field)401ÔÇö not authenticated (no token or expired token)403ÔÇö authenticated but not authorized for this resource409ÔÇö conflict (duplicate email, version mismatch)422ÔÇö validation failed (email format wrong, amount negative)429ÔÇö rate limit exceeded
Pagination, Filtering, and Sorting
Every list endpoint needs pagination from day one. Our standard pattern:
- Pagination:
?page=2&per_page=25ÔÇö default 25, max 100 - Sorting:
?sort=-created_at,nameÔÇö prefix with-for descending - Filtering:
?status=active&created_after=2025-01-01ÔÇö explicit filter parameters - Search:
?q=ramu+softÔÇö for full-text search across multiple fields
Always return pagination metadata in the response:
total,page,per_page,total_pages- Include
nextandprevlinks for cursor-based pagination
Error Responses: Be Helpful
A good error response tells the developer exactly what went wrong and how to fix it. Our standard error format includes an error code, a human-readable message, and field-level details for validation errors. The message should be specific enough that a developer can fix the issue without reading documentation.
Versioning Strategy
Use URL-based versioning: /api/v1/, /api/v2/. Header-based versioning is technically cleaner but practically harder to test and debug. When you release v2, keep v1 running for at least 6 months with deprecation headers.
Authentication and Rate Limiting
For most applications:
- API keys for server-to-server integrations (passed via
X-API-Keyheader) - JWT tokens for mobile and SPA clients (short-lived access + refresh token pattern)
- Rate limiting ÔÇö 100 requests/minute for authenticated users, 20/minute for public endpoints. Return
429withRetry-Afterheader
Conclusion
Good API design is about consistency and predictability. Pick conventions, document them, and stick to them across every endpoint. Your future self and every developer who integrates with your API will thank you.
Need a well-designed API for your application? Our development team builds APIs that developers love to integrate with.