The Complete Guide to REST APIs in 2026
A complete guide to REST APIs — the principles, HTTP methods and status codes, resource URL design, authentication, pagination, versioning and modern error handling (RFC 9457) — with examples throughout.
A REST API is the most common way software talks to software over HTTP — a web app fetching data, a mobile client saving a record, one service calling another. This complete guide covers what makes an API RESTful, the HTTP methods and status codes, how to design resource URLs, and the production concerns: authentication, pagination, versioning and error handling.
REST principles
- Resources — everything is a resource (a user, an order) with a URL. Use nouns, not verbs.
- Uniform interface — the same standard HTTP methods act on every resource.
- Stateless — each request carries everything needed; the server keeps no per-client session between requests. This makes APIs scalable.
- Representations — clients exchange representations of resources, usually JSON.
- Client–server separation — the client and API evolve independently behind the contract.
HTTP methods
Each method has a defined meaning. Using them correctly is most of what makes an API RESTful:
- GET — read a resource. Safe (no changes) and idempotent.
- POST — create a new resource (or trigger an action). Not idempotent.
- PUT — replace a resource entirely. Idempotent.
- PATCH — partially update a resource.
- DELETE — remove a resource. Idempotent.
GET /api/users # list users
GET /api/users/42 # get one user
POST /api/users # create a user
PUT /api/users/42 # replace user 42
PATCH /api/users/42 # update part of user 42
DELETE /api/users/42 # delete user 42
Status codes
The response status code tells the client what happened. Use the right one — clients branch on it:
- 2xx success —
200 OK,201 Created(with aLocationheader),204 No Content(e.g. after DELETE). - 3xx redirect —
301 Moved Permanently,304 Not Modified(caching). - 4xx client error —
400 Bad Request,401 Unauthorized(not authenticated),403 Forbidden(authenticated, not allowed),404 Not Found,409 Conflict,422 Unprocessable Entity,429 Too Many Requests. - 5xx server error —
500 Internal Server Error,503 Service Unavailable.
Designing resource URLs
Use plural nouns for collections, put the identifier in the path, and express relationships by nesting — but don’t nest too deeply. Keep verbs out of URLs; the HTTP method is the verb.
# ✅ good
GET /api/users/42/orders # orders for user 42
GET /api/orders?status=shipped # filter with query params
# ❌ avoid verbs in the path
GET /api/getUserOrders?id=42
Requests and responses
Most REST APIs exchange JSON. Set Content-Type: application/json on requests with a body, and return consistent, well-structured JSON. Include a top-level shape clients can rely on.
POST /api/users
Content-Type: application/json
{ "name": "Ada", "email": "[email protected]" }
// 201 Created
{ "id": 42, "name": "Ada", "email": "[email protected]" }
Authentication
Most APIs require the client to prove who it is. Common approaches, from simplest to most robust:
- API keys — a secret token in a header; simple, good for server-to-server.
- Bearer tokens / JWT — a signed token sent as
Authorization: Bearer <token>; stateless and widely used. - OAuth 2.0 / OIDC — delegated authorization for third-party access and "sign in with…" flows.
GET /api/orders
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
Pagination, filtering and sorting
Never return an unbounded list. Page large collections, and let clients filter and sort with query parameters. Cursor-based pagination scales better than offset for large or fast-changing data.
# offset pagination
GET /api/users?page=2&limit=20
# cursor pagination (scales better)
GET /api/users?limit=20&cursor=eyJpZCI6NDJ9
# filter + sort
GET /api/products?category=books&sort=-price
Versioning
APIs change; versioning lets you evolve without breaking existing clients. The most common approach is a version in the URL path. Version from day one so a v2 is possible later.
GET /api/v1/users
# or via header:
Accept: application/vnd.example.v1+json
Error handling
Return a helpful, consistent error body — not just a status code. The modern standard is RFC 9457 (Problem Details): a structured JSON error with type, title, status and detail. Never leak stack traces or internal details to clients.
// 422 Unprocessable Entity
Content-Type: application/problem+json
{
"type": "https://example.com/errors/validation",
"title": "Validation failed",
"status": 422,
"detail": "email must be a valid address",
"errors": [{ "field": "email", "message": "invalid format" }]
}
Idempotency and safety
A safe method doesn’t change server state (GET). An idempotent method produces the same result whether called once or many times (GET, PUT, DELETE). POST is neither, so for critical creates, support an idempotency key so a retried request doesn’t create duplicates.
POST /api/payments
Idempotency-Key: 9f2a1c7e-... # retry-safe create
REST API best-practices checklist
- Use nouns for resources and the correct HTTP method for the action.
- Return the right status codes; distinguish 401 from 403.
- Serve JSON with consistent shapes; always use HTTPS.
- Authenticate every non-public endpoint (API key, JWT, or OAuth).
- Paginate large collections; support filtering and sorting.
- Version the API from day one.
- Return structured errors (RFC 9457); never leak internals.
- Make critical creates idempotent with an idempotency key.
Frequently asked questions
What is a REST API?
What is the difference between PUT and PATCH?
How should I handle errors in a REST API?
type, title, status and detail, served as application/problem+json. Include field-level validation messages where useful, and never expose stack traces or internal details to clients.Should I use REST or GraphQL?
Build and test API calls live in XCODX Studio — run real code with npm packages in the browser. See also API design best practices, Node.js best practices and best HTTP client libraries.