APIs Are Products

When we build APIs at StrikingWeb, we treat them as products with their own users — other developers. Just as a well-designed user interface makes an application pleasant to use, a well-designed API makes integration straightforward and enjoyable. A poorly designed API, on the other hand, generates support tickets, causes integration bugs, and frustrates everyone involved.

This guide covers the principles and conventions we follow when designing REST APIs for our clients, whether they are building internal microservices, public developer platforms, or mobile application backends.

Use Nouns for Resource URLs

REST is built around the concept of resources, and your URLs should reflect this. Use nouns to name resources, not verbs. The HTTP method (GET, POST, PUT, DELETE) already specifies the action being performed.

// Good - nouns representing resources
GET    /api/users          // List users
GET    /api/users/42       // Get specific user
POST   /api/users          // Create a user
PUT    /api/users/42       // Update a user
DELETE /api/users/42       // Delete a user

// Bad - verbs in URLs
GET    /api/getUsers
POST   /api/createUser
POST   /api/deleteUser/42

Use plural nouns for collections (/users, not /user) and lowercase with hyphens for multi-word resources (/order-items, not /orderItems or /order_items).

Use HTTP Methods Correctly

Each HTTP method has a specific semantic meaning. Using them correctly makes your API predictable:

Return Proper HTTP Status Codes

Status codes communicate the result of an API request. Using them properly eliminates ambiguity:

Design Meaningful Error Responses

Error responses should help developers fix the problem quickly. A status code alone is not enough. Include a structured error body:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request contains invalid data",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address"
      },
      {
        "field": "age",
        "message": "Must be a positive integer"
      }
    ]
  }
}

Use a consistent error format across all endpoints. Include a machine-readable error code that clients can programmatically handle, a human-readable message for debugging, and field-level details for validation errors.

Implement Pagination

Any endpoint that returns a collection of resources should support pagination. Returning unbounded lists is a performance risk and can crash clients that attempt to load thousands of records into memory.

We recommend cursor-based pagination for real-time data and offset-based pagination for simpler use cases:

// Offset-based pagination
GET /api/users?page=2&per_page=25

// Response includes pagination metadata
{
  "data": [...],
  "meta": {
    "current_page": 2,
    "per_page": 25,
    "total": 150,
    "total_pages": 6
  }
}

Set sensible defaults (e.g., 25 items per page) and enforce maximum limits (e.g., 100 items per page) to prevent clients from requesting excessively large pages.

Version Your API

APIs evolve over time, and breaking changes are sometimes unavoidable. Versioning allows you to introduce changes without breaking existing integrations. The most common approaches:

We prefer URL versioning for most projects because it is explicit, easy to test in a browser, and clearly communicates which version is being used. Whichever approach you choose, commit to supporting old versions for a reasonable deprecation period (typically 6-12 months) and communicate upcoming changes through changelogs and deprecation warnings in response headers.

Use Filtering, Sorting, and Searching

Collection endpoints should support query parameters for filtering, sorting, and searching to give clients flexibility without requiring new endpoints for every data variation:

// Filtering
GET /api/users?status=active&role=admin

// Sorting
GET /api/users?sort=-created_at,name
// Prefix with - for descending order

// Searching
GET /api/users?search=john

// Combining
GET /api/users?status=active&sort=-created_at&page=1&per_page=25

Authentication and Security

API security is non-negotiable. Here are the essentials:

Document Your API

An undocumented API is unusable. Good documentation should include:

Tools like Swagger (OpenAPI), Postman, and Insomnia can help generate interactive documentation from your API specification. At StrikingWeb, we use OpenAPI specifications to maintain documentation that stays synchronized with the actual implementation.

A well-designed API reduces integration friction, lowers support costs, and makes your platform more attractive to developers. If you are building an API — whether for internal consumption or as a public developer platform — investing in good design upfront pays dividends throughout the API's lifetime.

Share: