Skip to main content
← All Articles ยท ยท 8 min read

REST API Design Best Practices 2026: Complete Guide

REST API design best practices 2026: resource naming, HTTP methods, status codes, versioning, pagination, error handling, HATEOAS, and OpenAPI documentation.

REST APIAPI designbest practicesHTTPOpenAPIversioning

REST APIs remain the backbone of modern web services. Yet poorly designed APIs create friction, bugs, and long-term maintenance nightmares. This guide consolidates the essential REST API design best practices for 2026 โ€” from URL structure to error handling and documentation.

1. Resource Naming: Nouns, Not Verbs

The single most common mistake in REST API design is using verbs in endpoint paths. REST uses HTTP methods to express actions โ€” your URLs should describe resources, not operations.

# Bad โ€” verb-based
GET /getUser/123
POST /createOrder
DELETE /deleteProduct/456

# Good โ€” noun-based, plural
GET /users/123
POST /orders
DELETE /products/456

Use plural nouns consistently. Nesting should reflect natural relationships, but avoid going deeper than two levels:

GET /users/123/orders          # User's orders โ€” good
GET /users/123/orders/456      # Specific order โ€” good
GET /users/123/orders/456/items/789/reviews  # Too deep โ€” avoid

For deeply nested resources, flatten them and use query parameters:

GET /reviews?userId=123&orderId=456&itemId=789

2. HTTP Methods and Their Semantics

Each HTTP method has a defined contract. Violating it breaks client expectations and caching behavior.

MethodSemanticsIdempotentSafe
GETRead a resourceYesYes
POSTCreate a resourceNoNo
PUTReplace a resource entirelyYesNo
PATCHPartially update a resourceNoNo
DELETERemove a resourceYesNo
# Replace entire user record
PUT /users/123
Content-Type: application/json

{ "name": "Alice", "email": "[email protected]", "role": "admin" }

# Update only the email
PATCH /users/123
Content-Type: application/json

{ "email": "[email protected]" }

Use PUT when the client sends the complete resource state. Use PATCH for partial updates. Never use GET for operations with side effects.

3. HTTP Status Codes Cheat Sheet

Return the most specific status code possible. Returning 200 OK for an error response is a common anti-pattern.

2xx Success
  200 OK             โ€” GET, PUT, PATCH success
  201 Created        โ€” POST created a resource (include Location header)
  204 No Content     โ€” DELETE success, or PATCH with no response body

3xx Redirection
  301 Moved Permanently  โ€” Resource URL changed permanently
  304 Not Modified       โ€” Client cache is still valid (ETag/If-None-Match)

4xx Client Errors
  400 Bad Request        โ€” Malformed request, validation failed
  401 Unauthorized       โ€” Not authenticated
  403 Forbidden          โ€” Authenticated but not authorized
  404 Not Found          โ€” Resource doesn't exist
  409 Conflict           โ€” State conflict (e.g., duplicate email)
  422 Unprocessable      โ€” Request syntax valid, but semantics fail
  429 Too Many Requests  โ€” Rate limit hit

5xx Server Errors
  500 Internal Server Error  โ€” Unexpected server failure
  503 Service Unavailable    โ€” Server temporarily down/overloaded

4. Versioning Strategies

APIs evolve. Versioning prevents breaking existing clients.

URL path versioning is the most widely adopted approach:

GET /v1/users/123
GET /v2/users/123

Custom header versioning keeps URLs clean:

GET /users/123
API-Version: 2026-04-01

Pick one strategy and apply it consistently. URL versioning is easier to test and bookmark; header versioning is more RESTful but harder to debug. Stripe uses date-based header versioning to great effect.

5. Pagination: Cursor vs Offset

For collections, always paginate. Two main strategies:

Offset pagination โ€” simple but has problems with large datasets and live data:

GET /users?page=3&limit=20
GET /users?offset=40&limit=20

Cursor pagination โ€” scalable and consistent for real-time data:

GET /users?cursor=eyJpZCI6MTIzfQ&limit=20

Response envelope for cursor pagination:

{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTQzfQ",
    "prev_cursor": "eyJpZCI6MTIzfQ",
    "has_next": true,
    "has_prev": true,
    "total": 1240
  }
}

Use cursor pagination for feeds, timelines, and large datasets. Use offset for admin panels where users jump to specific pages.

6. Error Responses โ€” RFC 7807 Problem Details

Never return plain strings as error responses. Use the RFC 7807 Problem Details standard:

{
  "type": "https://api.example.com/errors/validation-failed",
  "title": "Validation Failed",
  "status": 422,
  "detail": "The request body contains invalid fields.",
  "instance": "/users/register",
  "errors": [
    {
      "field": "email",
      "message": "Must be a valid email address",
      "code": "INVALID_EMAIL"
    },
    {
      "field": "password",
      "message": "Must be at least 8 characters",
      "code": "TOO_SHORT"
    }
  ]
}

Include machine-readable code fields so clients can handle specific errors programmatically without string-matching error messages.

7. HATEOAS โ€” Hypermedia as the Engine of Application State

Level 3 REST APIs embed links within responses to guide clients through available actions:

{
  "id": 123,
  "status": "pending",
  "total": 49.99,
  "_links": {
    "self": { "href": "/orders/123", "method": "GET" },
    "cancel": { "href": "/orders/123/cancel", "method": "POST" },
    "pay": { "href": "/orders/123/payment", "method": "POST" },
    "user": { "href": "/users/456", "method": "GET" }
  }
}

HATEOAS reduces coupling โ€” clients discover actions from responses rather than hardcoding URLs. Itโ€™s especially valuable for state machines like orders, workflows, and subscriptions.

8. OpenAPI 3.1 Basics

Document your API with an OpenAPI spec. Hereโ€™s a minimal example:

openapi: 3.1.0
info:
  title: Users API
  version: 1.0.0
paths:
  /users/{id}:
    get:
      summary: Get user by ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: User found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          description: User not found
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email
      required: [id, name, email]

Generate interactive docs with Swagger UI or Redoc. Use Spectral to lint your spec for rule violations before publishing.

9. Security: Rate Limiting and Authentication

Every public API needs rate limiting. Return 429 Too Many Requests with informative headers:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712066400

For authentication, use Bearer tokens in the Authorization header:

GET /users/123
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Additional security checklist:

  • Validate all inputs server-side, regardless of client validation
  • Use HTTPS everywhere โ€” no HTTP in production
  • Set Content-Security-Policy and X-Content-Type-Options headers
  • Never expose stack traces or internal errors to API consumers
  • Rotate API keys and support key revocation

Quick Reference Checklist

  • URLs use plural nouns, not verbs
  • HTTP methods match their semantic contract
  • Status codes are specific and accurate
  • Collections are paginated
  • Errors follow RFC 7807 format
  • API is versioned
  • Rate limiting is implemented
  • OpenAPI spec exists and is kept current
  • Authentication is required on protected routes
  • HTTPS enforced

Following these practices produces APIs that are intuitive, resilient, and easy to integrate. The best API design is the one that makes your consumers write less code to accomplish their goals.

Free Download

50 CLI Commands That Save Hours Every Week

The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.

  • Git mastery (10 cmds)
  • File & search wizardry
  • Docker & DevOps tricks
  • Process & network tools
  • Productivity boosters
  • macOS & Linux install guide

No spam. 1 email/week max. Unsubscribe anytime.

Found this guide useful? Check out our free developer tools.