5 Letter Words

Tech news, reviews and explainers Monday, November 2, 2026

API Design Principles: Simple Rules for Better APIs

Good API design principles are boring on purpose. Name things clearly, answer with the right status code, fail in one predictable shape, and developers you will never meet can use your API without asking you a single question.

api design principles

API design principles are the shared rules a team agrees on before it builds an API, so that every endpoint names things the same way, answers in the same shape and fails in the same style. An API, short for application programming interface, is the doorway one program uses to talk to another: it sends a request to an address, and the other program sends data back. When the doorway follows clear rules, strangers can walk through it without a guide. When it does not, every new user needs a meeting and a lot of patience.

The stakes are higher than they look. Code that calls your API hard-codes your choices into other people’s products. A confusing name or a surprise error format spreads into every app that depends on you, and stays there for years. That is why large companies treat APIs as long term contracts between systems, the same contracts that enterprise application integration work is built on, and why the biggest platforms publish their house rules for everyone to copy.

This guide walks through the principles that matter most, in the order a designer meets them: resources, methods, status codes, errors, versions, lists, safe writes, security and documentation. Each one comes with the weak version and the better version side by side, because API design principles are easier to learn from a bad address than from a definition.

The principles at a glance
Resources firstName things with nouns, and let the HTTP method carry the action
Honest codesUse status codes for what actually happened, never 200 for everything
One error shapeEvery failure answers in the same fields, so callers parse errors once
Gentle changeAdd freely inside a version, and break things only behind a new version
Safe by defaultPaginated lists, retry-safe writes, keys and limits from day one

Start with resources, not actions

The first of the core API design principles says an API is a set of things, not a set of commands. Those things are called resources: an order, a customer, a product, an invoice. Each resource gets an address, called a URI, and the address names the thing in plain nouns. The action lives in the HTTP method, the small word at the start of every request such as GET or POST. GET means read, POST means create, PUT and PATCH mean update, and DELETE means remove. Because the method already carries the verb, the address never needs one.

Microsoft’s API design guidance gives the same advice: base addresses on nouns, use plural nouns for collections, and keep nesting shallow, no deeper than collection, item, collection. So the orders of one customer live at /customers/5/orders, and one order sits at /orders/99. Anything deeper turns addresses into riddles and breaks the moment the business changes how things relate.

JobWeak designBetter design
Create an orderPOST /createOrderPOST /orders
Read one customerGET /getCustomer?id=5GET /customers/5
Delete an orderPOST /deleteOrder/9DELETE /orders/9
List productsGET /listAllProductsGET /products

One more habit separates tidy APIs from tangled ones: design around the business, not around the database. Tables split data for storage reasons that mean nothing to callers. If the people using the API think in orders and shipments, the API should speak in orders and shipments, even when the database underneath stores them differently.

rest api design principles

Use methods and status codes the way HTTP means them

HTTP hands every API a shared vocabulary, and good design uses it instead of inventing a private one. Five methods cover almost everything. GET reads and never changes anything. POST creates something new. PUT replaces a resource with the full copy the caller sends. PATCH changes only the fields the caller sends. DELETE removes. A caller who knows these five words can predict what an unfamiliar endpoint does before reading its documentation.

The reply carries a status code, a three digit number that reports the outcome before the caller reads any data. MDN’s reference of HTTP status codes lists them all, and they group into families: 2xx means success, 4xx means the caller sent something wrong, and 5xx means the server failed. Returning 201 after a creation tells the caller the new resource exists, and the reply can include its address. Returning 200 for every outcome, with the real result buried in the body, forces every caller to parse every reply just to learn whether the request worked.

Precision pays off most in the 4xx family. A 400 says the request itself is malformed. A 401 says the caller has not logged in, and a 403 says it logged in but lacks permission, two problems with very different fixes. A 404 reserves itself for things that do not exist, a 409 reports a clash with the current state, such as editing a record someone else just changed, and a 429 tells the caller to slow down. Each code gives the calling code a clear next move.

api design best practices

Keep one shape for success, and one shape for errors

Consistency is the quietest of the API design principles and the one callers feel most. A success reply should look the same on every endpoint: the same field names, the same date format, the same way of wrapping lists. If one endpoint calls it created_at and the next calls it dateCreated, every caller writes translation code forever. Pick a style for names, such as snake_case or camelCase, and hold it across the whole API without exceptions.

Errors deserve the same discipline, because error handling is where integrations go to die. The internet even has a standard for this: RFC 9457, the problem details specification, defines one JSON shape for reporting trouble, with a type that identifies the kind of problem, a short title, the status code, a detail written for humans and an instance that points at the exact request that failed. Callers can then handle every failure with one block of code, and support teams can search logs for one field instead of twenty creative ones.

Error fieldWhat it tells the caller
typeA stable identifier for this kind of problem, safe to program against
titleA short summary of that problem type, in plain words
statusThe same status code the reply already carries
detailWhat went wrong this specific time, written for a person
instanceWhich request failed, so support can find it in the logs

Two habits keep errors useful. First, never leak internals: an error that quotes a database message or a stack trace hands attackers a map of your system. Second, make the detail actionable. “Invalid request” helps nobody, while “quantity must be at least 1” fixes itself.

Version on purpose, not by accident

Every API changes, and API design patterns for change matter as much as the first release. The safe rule is simple: additions are free, removals are expensive. Adding a field, a new endpoint or an optional parameter never breaks existing callers, because old code ignores what it does not know. Renaming a field, changing its type or making an optional field required breaks every caller at once, so those changes belong in a new version.

Teams show the version in a few standard ways. Microsoft’s guidance lists the address itself, such as /v1/orders, a query string, a custom header and the media type, and notes that address and query versions stay friendly to caches because the version sits inside the address. The address style wins in practice because anyone can see it, test it in a browser and debug it from a log line. Whatever style a team picks, it should keep the old version alive while callers migrate, and publish a clear date for turning it off.

api design patterns

Paginate, filter and sort every big list

A list endpoint that returns everything works beautifully in testing, with twelve products, and badly in production, with twelve million. Pagination solves this by cutting a collection into pages. Callers pass a limit for how many items they want and either an offset for where to start or a cursor that points at the last item they saw. Microsoft’s guidance suggests sensible defaults, such as a page of 25, and a hard maximum, so one greedy request cannot drag the whole database across the network.

Filtering and sorting belong in the address as query parameters, like /products?status=active and a sort choice the caller controls, because different callers need different slices of the same collection. Every list reply should also report the total count and hand back the link or cursor for the next page, so callers never guess. Heavy list endpoints are the ones teams cache first, and a warmup cache request is how they refill that cache before real users arrive.

Make writes safe to retry

Networks drop answers. A caller sends a payment, the connection dies before the reply returns, and nobody knows whether the charge went through. The natural move is to send the request again, and without protection that retry charges the customer twice. HTTP already marks some methods as idempotent, which means repeating them has the same effect as doing them once: GET, PUT and DELETE behave this way by design. POST does not, and POST is exactly where payments and orders live.

The fix is an idempotency key. The caller invents a unique value for one action, often in an Idempotency-Key header, and sends the same key with every retry. The server stores the key with the first result; when the key shows up again, it returns the stored result instead of running the action twice. Automated pipelines lean on this daily: the retry logic inside AI data integration tools assumes a failed sync can run again safely. Any endpoint where a duplicate means real harm, such as charges, bookings or account creation, should accept a key from its first day.

good api design

Build security in from the first endpoint

Security belongs in the design, not in a patch after launch. Start with the two questions every request must answer. Authentication asks who is calling, usually proven with an API key or a token the caller received after logging in. Authorization asks what that caller may do. Mixing them up produces the classic bug where any logged in user can read any other user’s data by changing one number in the address.

Three more habits complete the picture. Least privilege means a key can do only the job it was issued for, so a read-only key can never delete anything even if it leaks. Rate limits cap how many requests a caller can make in a window and answer 429 past the cap; they blunt brute force attacks and the bulk harvesting described in our web scraping guide. And every input gets validated on the server, because the caller might be a bug, a bot or an attacker, never a trusted friend. Serve everything over HTTPS, and treat keys like passwords in logs and error messages.

Document with real examples, not promises

Documentation is part of API design, not an afterthought, because most callers judge an API by its docs before they judge it by its behavior. The practical standard is an OpenAPI description, a machine readable file that lists every endpoint, parameter and reply shape. Teams write it once and generate the pages, test clients and mock servers from it, so the docs cannot drift away from the real API.

Good pages follow a few rules. Every endpoint shows a complete example request and a complete example reply, including an error. Code samples appear in the languages callers actually use. And the quickstart takes a new developer from sign-up to a first successful call in minutes, because that first success decides whether they stay. The API design guidelines at large platforms treat docs as a launch requirement, and small teams win the same trust by copying the habit.

api design guidelines

Know when REST is not the right tool

Everything above assumes REST, the style built on resources and HTTP. Two other styles earn their place in specific jobs, and Google’s API design guide, the document Google has used internally since 2014, covers both REST and RPC designs. GraphQL lets the caller name the exact fields it wants in a single request, which suits apps that pull many related objects onto one screen and hate downloading fields they never show. gRPC defines services in Protocol Buffers and runs over HTTP/2; it trades human readability for speed and streaming, which suits servers talking to other servers inside one company.

Neither replaces the API design principles in this guide. A GraphQL schema still needs clear names, honest errors, pagination and authorization on every field. A gRPC service still needs gentle versioning and documentation people can follow. The style changes the envelope; the API design principles decide what callers find inside it.

api design principles checklist

Conclusion

API design principles reduce to one promise: act so the caller never has to guess. Resources with noun names, methods and status codes used the way HTTP defines them, one error shape, versions that respect existing code, lists that page safely, writes that survive retries, security built in from the start and documents drawn from the real thing. None of it is glamorous, and all of it compounds, because an API that teaches itself in an afternoon is the one other teams choose to build on.

Frequently asked questions

What is the most important API design principle?

Consistency. Callers forgive almost any single choice if the whole API makes that choice the same way everywhere. One naming style, one error shape and one way to page through lists teach themselves, while a mix of styles forces developers to relearn every endpoint.

Should an API use PUT or PATCH to update a resource?

Use PUT when the caller sends the complete resource and replaces what exists, and PATCH when the caller sends only the fields that change. Many APIs offer PATCH for everyday edits because sending one changed field is simpler and safer than resending the whole record.

How do you version an API without breaking existing apps?

Grow the current version by adding fields, endpoints and optional parameters, which old code safely ignores. Save a new version number, such as v2 in the address, for breaking changes like renaming a field, and keep the old version running while callers move over.

Written by

Ahmad Jajja

Ahmad covers AI, chips and the companies behind them. For this guide he checked every rule against the API design guidance that Microsoft and Google publish for their own platforms.

Reviewed by

Danish Mustafa

Danish reviews laptops, phones and home tech over weeks of real use, and fact-checks the numbers in our AI coverage. He verified the status codes and examples in this guide against the HTTP references.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top