# API Design: A Complete Guide — Routebase

> The decisions behind an HTTP API, in the order they arrive. Resources, methods, status codes, errors, pagination, idempotency and rate limits.

Canonical page: https://routebase.dev/guides/api-design/
Guide overview · 10 chapters · Last reviewed 2026-09-13 · The Routebase Team

You have already made these decisions. Every API has a resource model, a status code for a rejected write and a shape for its error bodies, whether or not anyone chose them on purpose.

The question is whether they were decided once and written down, or a hundred times by different people under deadline pressure. This guide covers the decisions themselves, in the order they arrive, and what each one costs when you get it wrong.

## The decisions arrive in an order

Design decisions are not a checklist you can work through in any sequence, because the early ones constrain the later ones.

_Figure: The resource model comes first because it decides what a URL can express, and everything downstream inherits it. Methods and status codes follow from the resources, error design has to cover every one of those operations, and the recurring patterns sit on top. Writing the OpenAPI document is the last step rather than the first, because the file records decisions instead of making them._

That order is also why so much design debt is expensive. Changing a pagination style touches every list endpoint, and changing a resource model touches every URL you have published.

## Why the specification is not the design

An OpenAPI document describes an interface precisely, and it is completely indifferent to whether the interface is any good.

You can write a valid document for an API with three different pagination styles, five error shapes and a `POST /doThing` in the middle of it. The file will validate, the reference documentation will render and the mock server will answer. None of those tools has an opinion about the decisions underneath.

So the specification is where a decision gets recorded and checked, and it is not where the decision gets made. The [OpenAPI guide](/guides/openapi/) covers the format itself, and this guide covers what you put in it.

## The cost of deciding twice

Almost every decision here has more than one defensible answer, and the difference between the answers is usually smaller than the difference between deciding once and deciding repeatedly.

Cursor pagination and offset pagination both work. What does not work is one collection paged by cursor, a second by page number and a third returning everything. A consumer writes the pagination loop three times, and the third one is where the bug lives.

This is the argument that runs through the whole guide. Where two options are genuinely close, the text says so and moves on to the thing that matters, which is applying whichever you picked everywhere.

## The short answer

If you take one rule from this guide, take this one. Decide each of these once, write the decision into the contract rather than into a wiki page, and put a check in the way of the next person who decides differently.

The rest of the guide is that rule taken apart.

| Chapter | Answers |
|---|---|
| [Resources and URLs](/guides/api-design/resources-and-urls/) | Nouns over verbs, when nesting helps and when it traps you |
| [Methods and status codes](/guides/api-design/http-methods-and-status-codes/) | What each method promises, and which code sets which expectation |
| [Designing API errors](/guides/api-design/designing-api-errors/) | One shape for every failure, and a way out of each one |
| [Actions that are not CRUD](/guides/api-design/actions-that-are-not-crud/) | Cancel, publish, retry, search, and the cost of each modelling |
| [Pagination, filtering and sorting](/guides/api-design/api-pagination-filtering-and-sorting/) | Offset against cursor, and what each costs under concurrent writes |
| [Idempotency and retries](/guides/api-design/idempotency-and-retries/) | Why callers retry, and what an idempotency key actually promises |
| [Rate limits](/guides/api-design/api-rate-limiting/) | What a limit tells a caller, and the headers that carry it |
| [Consistency across an API](/guides/api-design/consistency-across-an-api/) | Why consistency has to be a mechanism rather than an intention |
| [Design for the client you now have](/guides/api-design/designing-for-agent-clients/) | What changes when the caller reads your description at runtime |
| [Choosing a design tool](/guides/api-design/api-design-tools/) | The criteria that separate an editor from a design workflow |

Three neighbouring subjects live in other guides. The document format is covered in the [OpenAPI guide](/guides/openapi/), and what to do when a decision has to change is covered in [API versioning](/guides/api-versioning/). How a decision becomes an enforced rule runs through [consistency](/guides/api-design/consistency-across-an-api/) into the tooling. For a one-page summary of the same ground, the [API design principles](/blog/api-design-principles/) post is the short version this guide expands.

## In Routebase

Routebase is a structured API designer, so a decision lands in a form rather than in YAML, and the OpenAPI document is what it is stored as.

_Screenshot: The endpoint tree, the operation being edited and a real request against a selected environment sit in one window, so a design decision and the check that it holds are never two tools apart._

The decisions in this guide surface in three places in the product. Folders and tags carry the resource model, components and the organisation-level shared library carry the shapes you reuse, and the style guide turns a convention into a check that runs while you type. Start with the [Endpoints guide](https://docs.routebase.dev/endpoints/) in the product documentation, or read on. The [API design feature page](/api-design/) has the short version of how the designer fits into the rest of the lifecycle.

## Frequently asked questions

### What is API design?

API design is the set of decisions that fix what an HTTP interface promises before any of it is built. Those decisions cover which resources exist and what they are called, which method does what, and which status code comes back. They also cover what an error looks like, how a long list is paged and what happens when a caller retries. Writing the specification records those decisions, and it does not make them for you.

### What are the most important API design decisions?

Four of them shape everything that follows. The resource model decides what your URLs can express, and the method and status code semantics decide what a caller may assume. The error format decides how a client recovers, and the pagination style decides whether a list endpoint survives its own growth. Each of those is expensive to change later, because each one is visible to every consumer.

### Should you design an API before writing code?

Designing first is worth it when more than one team depends on the result, because the contract becomes something they can build against in parallel. It is worth less on an interface with a single consumer that ships in the same commit. The real question is not the order of the work but whether the contract ends up written down somewhere a machine can check.

### What makes an API easy to use?

Predictability, more than any single convention. A caller who has used three of your endpoints should be able to guess the fourth, get the error they expect in the shape they expect, and page through a list the same way everywhere. Consistency is worth more than the individual choices it applies, which is why picking a convention and holding to it beats picking the best one.

## Chapters in this guide

1. [Resources and URLs](https://routebase.dev/guides/api-design/resources-and-urls/): How to pick the things your API exposes, why nesting stops paying after one level, what a path convention is worth, and which identifiers are safe to put in a URL.
2. [Methods and Status Codes](https://routebase.dev/guides/api-design/http-methods-and-status-codes/): What each HTTP method promises a caller, why PUT and PATCH are not interchangeable, and which status code sets which expectation, with the RFC behind each one.
3. [Designing API Errors](https://routebase.dev/guides/api-design/designing-api-errors/): One shape for every failure, why an error code is a contract and a message is not, what belongs in a problem document, and what has to stay out of it.
4. [Actions That Are Not CRUD](https://routebase.dev/guides/api-design/actions-that-are-not-crud/): Cancel, publish, retry, search and bulk edit, modelled three different ways, with what each modelling costs and the questions that decide between them.
5. [Pagination, Filtering and Sorting](https://routebase.dev/guides/api-design/api-pagination-filtering-and-sorting/): Offset against cursor and what each costs when the data changes underneath, why limits are not optional, and how much of the filter and sort syntax is actually standardised.
6. [Idempotency and Retries](https://routebase.dev/guides/api-design/idempotency-and-retries/): Why a timeout is ambiguous, what an idempotency key actually promises, how long a stored result has to live, and which parts of the pattern are standardised.
7. [Rate Limits as a Design Decision](https://routebase.dev/guides/api-design/api-rate-limiting/): What a published limit promises a caller, why 429 needs Retry-After, how little of the header convention is standardised, and what a limit should be counted against.
8. [Consistency Across an API](https://routebase.dev/guides/api-design/consistency-across-an-api/): Why the same decision has to appear at every endpoint, why intention is not a mechanism, and the three things that actually hold a convention in place over time.
9. [Design for the Client You Now Have](https://routebase.dev/guides/api-design/designing-for-agent-clients/): Hypermedia promised runtime discovery to clients that were all generated ahead of time. A caller that reads your description at runtime finally exists, and it reads the prose.
10. [What to Look for in an API Design Tool](https://routebase.dev/guides/api-design/api-design-tools/): Eight criteria that decide whether a design tool still helps in a year, written as questions to ask rather than as a list of vendors.

---

[Routebase](https://routebase.dev/) — [Sign up](https://app.routebase.dev/): Every account starts with a 14-day Pro trial — no credit card required.
