The API is the backbone of modern software. It connects services, powers mobile apps, and enables data exchange across complex systems. But not all APIs are created equal, and the gap between a frustrating API and one developers actually enjoy using usually comes down to a handful of concrete design decisions.
This article covers seven RESTful API best practices that matter in practice, with actionable guidance on URL design, authentication, versioning, error handling, and documentation.
- Proper HTTP Method and Status Code Usage
- Consistent and Intuitive URL Structure
- Authentication and Authorization
- Standardized JSON Payloads
- Error Handling
- API Versioning
- Documentation
1. Use Proper HTTP Methods and Status Codes
HTTP verbs and status codes are the core language of REST. Using them correctly makes your API predictable and lets network intermediaries like proxies, gateways, and caches do their jobs properly.
A GET retrieves data, POST creates, PUT or PATCH updates, and DELETE removes. That's the contract. When developers know this, they can reason about your API before reading a single line of docs.

HTTP Methods
- GET: Retrieves a resource or collection. Safe and idempotent.
- POST: Creates a new resource. Neither safe nor idempotent.
POST /userscreates a new user. - PUT: Replaces an existing resource entirely. Idempotent. Missing fields should be nulled or defaulted.
- PATCH: Applies partial modifications. Only send the fields you want to change.
- DELETE: Removes a resource. Idempotent.
Status Codes That Actually Mean Something
Don't return 200 OK for everything. Use specific codes.
- 201 Created: After a successful
POST. Include the new resource in the body and aLocationheader. - 204 No Content: Ideal for
DELETE. Success, nothing to return. - 400 Bad Request: Malformed syntax or invalid framing on the client side.
- 422 Unprocessable Entity: Syntax is fine, but the content fails validation (missing required field, wrong format, etc.).
Key Insight: Avoid a common anti-pattern of returning a
200 OKstatus code for every successful-looking request, including creations or deletions. Use specific codes to convey more precise information.
GitHub uses GET /repos for listing repositories. Stripe returns 201 after a payment is created. These aren't accidents. You can also learn how social media APIs implement these standards.
2. Design Consistent and Intuitive URL Structure
A good URL structure is self-documenting. If a developer knows GET /users returns a list of users, they can guess GET /users/123 fetches a specific one. That kind of predictability reduces cognitive load and speeds up integration.

URL Design Principles
- Nouns, not verbs: URLs represent resources. The HTTP method handles the action. Use
/users/123, not/getUserById/123. - Plural collection names:
/productsfor the collection,/products/456for a single item. - Consistent naming: Pick one convention (lowercase + hyphens is common) and stick to it everywhere.
/order-itemsbeats/orderItemsfor readability and SEO. - Limit nesting depth: One or two levels is usually enough.
/customers/123/ordersworks. Going deeper gets messy.
Real-World Examples
- Shopify:
GET /admin/api/customers/{customer_id}/orders - Stripe:
GET /v1/customers/{customer_id}/invoices - GitHub:
GET /users/{username}/repos/{repo}/issues
Key Insight: Think of your URL structure like a file system. A clear hierarchical path makes navigation intuitive. GitHub's
GET /users/{username}/repos/{repo}/issuesis a good example, showing exactly where issues live in relation to their repo and owner.
3. Implement Proper Authentication and Authorization
Security isn't optional. Authentication proves identity; authorization determines what an authenticated user can actually do. Both matter, and both need to be implemented correctly.
A user authenticated to GET /users/me shouldn't be able to hit GET /users/123 for someone else's data. These are different things, and your API needs to enforce that distinction.

Authentication Options
- OAuth 2.0: The standard for delegated authorization. Lets third-party apps access resources on behalf of a user without exposing credentials. Google, Facebook, and GitHub all use it with defined scopes (
read:profile,write:posts, etc.). - JWT (JSON Web Tokens): Self-contained, signed tokens for stateless authentication. The client gets a JWT at login and sends it in the
Authorizationheader on subsequent requests. - API Keys: Simpler, mostly used for server-to-server communication. A unique key per client, sent as a header like
X-API-Key. Requires rotation policies.
Implementation Checklist
Key Insight: Never send credentials, tokens, or API keys over plain HTTP. Always enforce HTTPS for all communication.
- Short-lived access tokens: 15-60 minutes limits the blast radius if a token is compromised.
- Refresh tokens: Pair with short-lived access tokens so clients can stay authenticated without forcing re-login.
- Scope-based authorization: Define granular permissions. An app requesting
read-onlyaccess shouldn't be able to delete anything. - Token revocation: Implement logout endpoints that immediately invalidate both access and refresh tokens.
You can also see how these principles apply in practice with API integration best practices.
4. Use JSON for Request and Response Payloads
JSON has won. It's lightweight, human-readable, and natively supported in every language worth caring about. Stripe, Shopify, Twitter all standardized on it. There's no good reason to deviate.

JSON Tips That Actually Matter
- Set headers correctly: Always include
Content-Type: application/json. It tells caches, firewalls, and clients how to interpret the payload. - Pick a naming convention and stick to it:
camelCaseorsnake_case, your call. Just don't mix them.camelCasealigns with JavaScript natively, which is often a good enough reason. - Use
nullfor absent values: Don't omit keys or use empty strings.nullis explicit and clear. - Validate schemas: Reject malformed requests early on the server side. A JSON schema for your responses also helps developers understand your data structures.
Handling Bad JSON
If a client sends invalid JSON, don't return a generic 500. Return 400 Bad Request with a clear message.
{
"error": {
"type": "invalid_request_error",
"message": "Invalid JSON format: Unexpected token } in JSON at position 54"
}
}
Stripe does this well. Actionable errors help developers fix their integration fast.
5. Implement Comprehensive Error Handling
How your API handles failures says a lot about its overall quality. Vague errors waste developer time. Structured, specific errors save it.
When a request fails, developers need to know what happened, why it happened, and ideally how to fix it. Getting that right dramatically reduces support requests and speeds up integration.
What a Good Error Response Includes
- Consistent structure: Every error should follow the same JSON format, regardless of endpoint. This lets developers write generic error handling logic.
- Machine-readable error codes: Unique strings like
invalid_api_keyormissing_required_fieldallow programmatic handling. - Human-readable messages: Plain English, aimed at the developer. Not the end user.
- Contextual details: For validation errors, say which field failed. For rate limit errors, say when it resets.
- Request ID: A unique ID per request makes it easy to correlate logs when someone contacts support.
Examples Worth Studying
Key Insight: Treat your error responses as part of your API's user interface. A well-crafted error message is as important as a well-designed success response.
- Stripe: Returns
type,code, andmessagein a consistent error object. The gold standard. - GitHub: Includes a
documentation_urlin errors pointing to the relevant docs section. - RFC 7807: "Problem Details for HTTP APIs" defines a standardized format for machine-readable error details. Worth adopting.
6. Implement an API Versioning Strategy
APIs evolve. Features get added, data models change, things get deprecated. Without versioning, a single deployment can break every client integration out there.
A clear versioning strategy gives developers a stable surface to build on, and a predictable migration path when things change.
Common Versioning Approaches
- URL path versioning:
https://api.example.com/v1/users. Simple, explicit, easy to see which version you're on. GitHub uses this. - Header versioning: The version goes in a request header (
Accept: application/vnd.example.api.v1+json). Cleaner URLs, but less visible. Stripe uses a variant of this with date-based version strings. - Query parameter versioning:
https://api.example.com/users?version=1. Fine for testing, but clutters production URLs.
Versioning Best Practices
Key Insight: Only introduce a new major version for breaking changes. Adding optional fields or fixing bugs doesn't require a version bump.
- Define what counts as a breaking change: Removing endpoints, changing data types, making optional params required. These need a new version.
- Keep a public changelog: Developers need to know what changed and when.
- Set a deprecation timeline: Support the previous major version for at least 6-12 months. Give people time to migrate.
- Communicate proactively: Send notices before deprecation, not after.
For more on controlling API usage across versions, see API rate limit best practices.
7. Write Good API Documentation
An API without good docs is half an API. Documentation is what turns a working API into one developers can actually adopt and build on. It reduces support requests, speeds up onboarding, and often determines whether someone integrates with you or gives up and tries something else.
What Good Docs Look Like
- Endpoint descriptions: What each endpoint does, its path, supported methods, and how it relates to other resources.
- Request/response examples: Copy-paste-ready examples for every endpoint. Both success and error cases.
- Authentication guide: Step-by-step. Don't assume anything.
- Code samples: Multiple languages. Python, JavaScript, and at least one more.
- Interactive testing: Let developers make live API calls from the docs page.
Tools and Standards
Key Insight: Treat your documentation as a first-class product. The best approach is generating it directly from your API spec or source code so it stays in sync.
- OpenAPI Specification: The industry standard for defining REST APIs. Write an OpenAPI file in YAML or JSON and use it to generate docs, client SDKs, and server stubs automatically.
- Swagger UI / Redoc / GitBook: Render your OpenAPI spec as readable, interactive documentation.
- API-first development: Stripe and Twilio are the benchmark here. Their docs are a product in themselves, with guides, tutorials, and interactive examples throughout. The Stripe API documentation is worth studying.
8. Best Practices Comparison Guide
| Item | Implementation Complexity | Resource Requirements | Expected Outcomes | Ideal Use Cases | Key Advantages |
|---|---|---|---|---|---|
| Use Proper HTTP Methods and Status Codes | Medium – requires HTTP knowledge and discipline | Low – standard HTTP tooling and middleware | Predictable API behavior; better caching and error handling | APIs following REST standards for CRUD operations | Intuitive behavior; improved debugging; web standards compliance |
| Design Consistent and Intuitive URL Structure | Low to Medium – planning and consistency needed | Low – mainly design effort | Self-documenting and easy-to-navigate API endpoints | RESTful APIs requiring clear resource identification | Intuitive URLs; easier documentation; better caching and bookmarking |
| Implement Proper Authentication and Authorization | High – complex security mechanisms and management | Medium to High – needs security infrastructure | Secured API access; fine-grained permission control | APIs exposing sensitive or restricted data | Protects data; scalable user management; standard security practices |
| Use JSON for Request and Response Payloads | Low – widely supported format | Low – built-in language support | Lightweight, human-readable data exchange | Most modern APIs requiring cross-platform support | Universal language support; rich tooling; easy debugging |
| Implement Comprehensive Error Handling | Medium – consistent design and implementation | Low to Medium – additional development | Better developer experience; fewer support requests | APIs targeting high developer usability | Detailed errors; improved debugging; supports automated testing |
| Implement API Versioning Strategy | Medium to High – ongoing management | Medium – maintenance and documentation | Backward compatibility; smooth API evolution | APIs expected to evolve and maintain old clients | Manages breaking changes; supports gradual migration; clear timelines |
| Add Comprehensive API Documentation | Medium – requires continuous updates | Medium – tools and documentation effort | Faster onboarding; increased adoption | Public APIs targeting external developers | Improves adoption; reduces support; interactive and complete docs |
Putting It All Together
These seven practices aren't independent checklists. They reinforce each other. Consistent URL naming complements clear error messages. A strong auth layer needs a versioning strategy to handle breaking changes securely. When they all work together, you get an API that's actually pleasant to use and easy to maintain.
A few things to take away:
- Consistency matters most: From endpoint naming to JSON structure, predictability reduces cognitive load. Developers shouldn't have to guess.
- Your API communicates through more than data: Status codes, error messages, and documentation are all part of the interface. Silence or ambiguity is a design failure.
- Security from day one: Auth isn't something you bolt on later. It protects you, your platform, and your users.
Why This Matters Beyond Clean Code
A well-designed API becomes a product. It lowers the barrier for third-party developers, creates an ecosystem around your platform, and can generate use cases you hadn't anticipated. When developers like using your API, they talk about it. That's free growth.
Key Insight: Treat your API as your most important user interface. For many developers, your API is your product. Its design, usability, and reliability directly reflect on your brand.
Next Steps
- Audit one of your existing APIs against these seven principles. Where are the gaps? Pick the lowest-hanging fruit and fix it this week.
- Talk to your developers: If your API has users, ask them where they get stuck. Their frustrations are your roadmap.
- Write an internal API design guide: As your team grows, documented standards are the only way to keep quality consistent across services.
If you're managing complex scheduling needs across multiple social media platforms, you know the power of a well-built API. At LATE, we built our social media scheduling API on these very principles to ensure it's reliable, scalable, and easy to integrate. Explore how a best-in-class API can streamline your entire content workflow at LATE.

Miquel is the founder of Late, building the most reliable social media API for developers. Previously built multiple startups and scaled APIs to millions of requests.
View all articlesLearn more about Late with AI
See what AI assistants say about Late API and this topic