Guide

An API is a promise. Once another team, a mobile app or a paying customer depends on it, you can change the code behind it whenever you like. Changing the contract itself is slow, political and sometimes impossible. Mobile apps stay installed for years. Customers write an integration once and never touch it again. The implementation is temporary. The interface is close to permanent.

That makes API design a core system design skill. In an interview, the API is usually the first concrete thing you write after the requirements. It shows what data must exist and which operations must be fast. At work, a good API lets teams move on their own. A bad one becomes a tax that every caller pays.

Read the pages below in order. They cover the styles, the method rules, and the choices that are hard to change later.

Concepts on this topic

StepConceptWhat it answers
1API stylesREST, gRPC or GraphQL?
2Safe methods and idempotencyWhich calls are safe to retry?
3Cursor paginationHow do you page a list that keeps changing?
4API versioningHow do you change a contract without breaking callers?
5Structured errorsWhat should a failed call tell the caller?
6Webhooks and long-running operationsHow do you handle work that outlives the request?

Common mistakes

  • Adding pagination later. An endpoint that returned a plain list becomes a breaking change once you paginate it. Paginate from day one.
  • Unkeyed creates. A POST that charges money or creates a file must accept an idempotency key, or a timeout turns into a duplicate.
  • Sending big files through the API. A 10 GB upload should go straight to object storage through a signed URL, not through an app server.
  • Unwritten change policy. Teams that don't write down what counts as breaking end up arguing in every review.

A file-sharing API, briefly

Take a Dropbox-style service. Users upload files into folders and share them. A reasonable API looks like this:

POST   /v1/folders                         create a folder
GET    /v1/folders/{id}/children           ?cursor=&limit=50, cursor paginated
PATCH  /v1/files/{id}                      requires If-Match
POST   /v1/uploads                         returns pre-signed part URLs
POST   /v1/uploads/{id}:complete           turns the parts into a file
GET    /v1/files/{id}/content              302 to a short-lived signed URL
GET    /v1/changes?cursor=                 changes feed for sync clients

The key choices, and why:

  • Uploads skip the API servers. Clients send bytes to storage. The API handles metadata only.
  • Clients send size and sha256 first. The server can enforce quota early and detect duplicates.
  • Moves and renames use If-Match. Two devices can't silently overwrite each other.
  • A changes feed with a cursor. Sync clients ask "what changed since I last looked?" instead of re-listing everything.

Review checklist

Use this on any API, including your own:

  • Resources are nouns with stable, prefixed IDs.
  • Every create or action endpoint accepts an idempotency key.
  • Every list is paginated, with a total sort order and a page cap.
  • Errors use one format, with stable codes and clear retryability.
  • Concurrent updates are protected with ETags or version fields.
  • Long work returns 202 and an operation. Webhooks are signed and deduplicable.
  • Rate limits return 429 with Retry-After.

Key takeaways

  • An API is a long-lived contract. Design for additive change so you rarely need a new version.
  • Make every retryable write safe with idempotency keys.
  • Use cursor pagination with a unique tiebreaker, and cap the page size.
  • Return structured errors with stable codes, and send large data straight to storage.

Further learning

Joshua Bloch's classic talk is about library APIs, but its principles, such as "easy to use, hard to misuse", apply to web APIs too.

How To Design A Good API and Why it MattersGoogle TechTalks

A short visual explanation of RPC and gRPC, including HTTP/2 and Protobuf:

What is RPC? gRPC Introduction.ByteByteGo
Google Cloud API Design GuideA set of guidelines for designing APIs that are consistent with Google AIPs.Google Cloud Documentation Microsoft REST API GuidelinesMicrosoft REST API Guidelines. Contribute to microsoft/api-guidelines development by creating an account on GitHub.GitHub RFC 9457: Problem Details for HTTP APIsThis document defines a "problem detail" to carry machine-readable details of errors in HTTP response content to avoid the need to define new error response formats for HTTP APIs. This document obsoletes RFC 7807.rfc-editor.org APIs as infrastructure: future-proofing Stripe with versioningstripe.com gRPC documentationA high-performance, open source universal RPC frameworkgRPC