REST API Design Best Practices for Growing Products
REST API design best practices for Indian product teams: resource naming, status codes, pagination, errors, versioning and idempotency, with a pre-launch checklist.
Summary of this article
- Defines a REST API and explains why design decisions made early are hard to change once clients depend on them.
- Covers resource naming, HTTP methods and status codes, and a single consistent error format based on RFC 9457.
- Explains pagination, filtering, versioning and safe retries with idempotency keys for payment and order flows.
- Compares common design mistakes with their fixes, lists a pre-launch checklist and describes how Arham Technology designs APIs.
Summarised by AI from the full article. Check figures and prices against the article before you act on them.

Quick answer
Good REST API design means predictable resource-based URLs, correct HTTP methods and status codes, one consistent error format, pagination on every list, an explicit versioning plan and idempotent write operations. Agree the contract in an OpenAPI file before coding, so web, mobile and partner teams can build in parallel without rework.
Key takeaways
- Name URLs after resources (nouns), let the HTTP method carry the action, and keep naming identical across every endpoint.
- Return one error shape for every failure. RFC 9457 problem details is a ready-made standard for it.
- Paginate every list from day one, because adding pagination later breaks existing clients.
- Make payment, order and webhook writes safe to retry with idempotency keys.
- Write the OpenAPI contract first, and treat any change that removes or renames a field as a new version.
On this page
- What is REST API design, and why does it matter?
- How should you name resources and URLs?
- Which HTTP methods and status codes should you use?
- How should an API return errors?
- How do you handle pagination, filtering and sorting?
- When and how should you version an API?
- How do you make writes safe to retry?
- Common REST API mistakes and how to fix them
- Why should you write the API contract first?
- REST API pre-launch checklist
- How Arham Technology approaches REST API design
- Next step
Most API problems do not show up in the first demo. They appear six months later, when a mobile app, a partner integration and your own web frontend all depend on endpoints that were named in a hurry. If you are planning REST API design best practices for a product that is about to grow, the cheapest time to get them right is before the first client ships.
This guide covers the decisions that matter most for Indian product teams: naming, methods, errors, pagination, versioning, safe retries and documentation. It ends with a checklist you can use before launch.
What is REST API design, and why does it matter?
A REST API is an HTTP interface organised around resources, such as customers, orders and invoices, that clients read and change using standard methods like GET, POST, PATCH and DELETE. Design matters because every client you ship, whether a web app, an Android app or a partner system, becomes a promise you cannot break cheaply.
A badly designed API is not just untidy. It causes duplicate orders when a request is retried, support tickets nobody can debug, and frontend teams blocked while backend endpoints change. A well-designed one lets different teams build in parallel and lets you add features without breaking what already works.
How should you name resources and URLs?
Name URLs after resources, using plural nouns, and let the HTTP method describe the action. For example, GET /orders/1042 reads an order and POST /orders creates one, rather than /getOrder or /createNewOrder.
A few rules keep naming predictable:
- Use plural nouns for collections:
/customers,/invoices,/products. - Nest only one level where ownership is obvious:
/orders/1042/items. Deeper nesting becomes hard to read. - Use one casing style in URLs and JSON fields, and never mix them.
- Avoid verbs in paths, except for genuine actions that are not CRUD, such as
POST /orders/1042/cancel. - Use stable identifiers that do not leak internal details, such as UUIDs or opaque IDs instead of raw sequential numbers where enumeration is a risk.
Consistency matters more than any single rule. If one endpoint says customer_id and another says customerId, every client developer will notice.
Which HTTP methods and status codes should you use?
Use each method for its defined purpose and return a status code that tells the client what happened without parsing the body. The HTTP semantics are defined in RFC 9110, and most business APIs need only a small subset.
| Action | Method | Success code | Common error codes |
|---|---|---|---|
| Read one or a list | GET | 200 | 404 not found |
| Create a resource | POST | 201 with the new resource | 400 or 422 validation, 409 conflict |
| Update some fields | PATCH | 200 | 404, 422 |
| Replace a resource | PUT | 200 | 404, 422 |
| Delete a resource | DELETE | 204 no content | 404 |
| Any protected call | any | as above | 401 not signed in, 403 not allowed, 429 too many requests |
Two mistakes are especially common. The first is returning 200 OK with {"success": false} in the body, which breaks monitoring and client libraries that rely on status codes. The second is using 401 and 403 interchangeably: 401 means the caller is not authenticated, and 403 means they are authenticated but not permitted.
How should an API return errors?
Return one error format for every failure, so clients write one error handler instead of twenty. The IETF has published a standard for this: RFC 9457, Problem Details for HTTP APIs, which obsoletes the older RFC 7807.
A problem details response is JSON with the content type application/problem+json and a few well-known fields:
type: a URI that identifies the kind of problem.title: a short, human-readable summary.status: the HTTP status code.detail: an explanation specific to this occurrence.- Extra fields of your own, such as a list of invalid input fields.
Never put stack traces, SQL errors or internal server names in error responses. Log them on the server with a request ID and return that ID to the client, so support can find the exact failure without exposing internals.
How do you handle pagination, filtering and sorting?
Paginate every endpoint that returns a list, from the first release. Adding pagination to an endpoint that used to return everything breaks existing clients and, as data grows, can bring the server down.
There are two common approaches:
- Page and limit (
?page=3&limit=25) is simple and fine for admin screens and small datasets. - Cursor-based (
?after=abc123&limit=25) stays fast and consistent when rows are added while the user scrolls, which suits feeds, order histories and large tables.
Set a sensible default and a hard maximum for limit, so no client can request a million rows. Keep filtering and sorting in query parameters, such as ?status=paid&sort=-created_at, and whitelist the fields people can filter on so they cannot trigger unindexed queries.
When and how should you version an API?
Version an API when you make a breaking change, and only then. Adding an optional field or a new endpoint is not breaking. Removing a field, renaming it, changing its type or changing its meaning is.
The simplest approach is a path version such as /v1/orders, because it is visible in logs, documentation and support tickets. When you must release /v2, keep /v1 running for an announced period and tell integrators the end date in writing. Mobile apps are the reason this matters: users on old app versions keep calling old endpoints for months.
How do you make writes safe to retry?
Make any operation that moves money, creates an order or sends a message safe to repeat, because networks fail and clients retry. Without protection, a timeout on a payment request can create two charges.
The usual pattern is an idempotency key: the client sends a unique value in an Idempotency-Key header with a POST request, and the server stores the key with the result. If the same key arrives again, the server returns the stored response instead of repeating the action. Payment gateways commonly work this way, and the pattern is just as useful for your own order, booking and webhook endpoints. An IETF draft describes the header, but it has not become an RFC yet, so document your own rules clearly: how long keys are kept and what happens if the same key arrives with a different body.
Webhooks from Razorpay, WhatsApp or courier partners need the same care. Providers can deliver the same event more than once, so store the event ID and ignore repeats.
Common REST API mistakes and how to fix them
| Mistake | Why it hurts | Fix |
|---|---|---|
Verbs in URLs (/getUsers) |
Inconsistent, hard to guess | Plural nouns plus HTTP methods |
200 OK for errors |
Breaks monitoring and client libraries | Correct 4xx and 5xx codes |
| Lists with no pagination | Slow responses, timeouts | Default and maximum limit |
| Different error shapes per endpoint | Clients need many handlers | One problem details format |
| Breaking changes in place | Old mobile apps stop working | New version, announced sunset date |
| No retry protection on payments | Duplicate charges or orders | Idempotency keys, stored event IDs |
| Undocumented behaviour | Integrations take weeks | OpenAPI contract kept in the repo |
Why should you write the API contract first?
Write the contract before the code, so the frontend, mobile and partner teams are not waiting for the backend to exist. The OpenAPI Specification is the standard machine-readable format for describing REST APIs, and one OpenAPI file can generate documentation, mock servers, client SDKs and automated contract tests.
In practice, a contract-first workflow looks like this:
- List the resources and the screens or integrations that need them.
- Draft paths, request bodies, responses and error cases in an OpenAPI file.
- Review it with the frontend and any partners before writing server code.
- Generate a mock server so clients can start building immediately.
- Implement and test against the contract, failing the build if the code and the file disagree.
This is also the cheapest moment to change your mind. Editing a YAML file costs minutes, and editing a shipped API costs weeks.
REST API pre-launch checklist
Before you open an API to real clients, confirm each of these:
- Resource names are plural nouns and use one casing style everywhere.
- Every endpoint returns correct status codes, and errors use one format.
- All list endpoints have pagination, a default limit and a maximum limit.
- Authentication, authorisation and rate limiting are enforced on the server for every route.
- Write endpoints for payments, orders and webhooks are idempotent.
- The OpenAPI file matches the running code and is published for integrators.
- Logs carry a request ID, and you can trace a failed call end to end.
- A versioning and deprecation policy exists in writing.
If you are choosing a server stack alongside this, our comparison of Node.js vs Laravel for backends explains how each handles APIs, and the same design rules apply to both.
How Arham Technology approaches REST API design
Our backend development service treats the API as a product with its own contract. For each project we follow the same sequence:
- Domain and threat sketch: we map entities, trust boundaries and the abuse cases that matter for your product.
- Contract first: OpenAPI or an equivalent contract is agreed so frontend and partners can build in parallel.
- Core services build: authentication, primary resources and critical workflows ship with automated tests around the rules that must never break.
- Integration and load checks: third-party adapters are built with retries and idempotency, and key paths are exercised under expected load.
- Runbook handover: deploy steps, migration notes and incident basics are documented for your team.
We build REST APIs in Node.js and Laravel, depending on your team and product. If you are designing the API for a subscription product, our SaaS development service and our guide to building a SaaS MVP show how API decisions connect to scope and budget.
Next step
If you have an existing API that has grown messy, or a new product that needs a clean contract before development starts, bring your feature list and any current endpoint documentation. We will review it and suggest a practical plan. Learn more about our backend development service or contact us to talk through your project.
Frequently asked questions
What is the difference between REST and a normal API?
REST is a style for designing HTTP APIs around resources, standard methods and stateless requests. A normal or ad-hoc API can expose any URL or action name it likes, which makes it harder to learn and maintain. Most business APIs described as REST follow these conventions loosely, and that is usually enough.
Should I use PUT or PATCH to update a record?
Use PATCH when the client sends only the fields that changed, and PUT when it replaces the whole resource. Most product APIs use PATCH for edits because it is smaller and avoids overwriting fields the client never loaded. Document whichever you choose and apply it everywhere.
How should I version a REST API?
The simplest approach is a version in the URL path, such as /v1/orders, because it is visible in logs, docs and support tickets. Add a new version only for breaking changes like removing or renaming a field. Adding optional fields should not need a new version.
Is REST or GraphQL better for a startup?
REST is usually the safer default because it is simpler to cache, secure, monitor and hand over to new developers. GraphQL helps when many different clients need very different shapes of the same data. Start with REST and add GraphQL only when a real need appears.
How much does it cost to build a REST API in India?
An indicative range for a focused API with authentication, a few core resources and documentation is โน1,50,000โโน6,00,000, with larger multi-role products costing more. Integrations, testing and the number of resources move the price more than the language or framework.
Want Backend Development done right?
Get a free consultation and a clear plan โ scope, timeline and cost โ from our Mumbai team.



