Playbook · APIs

Designing a public API

Designing an API as a long-lived contract — versioned, documented and stable for its consumers.

What is this? · Playbook

A repeatable approach to a recurring challenge — situation, steps, decision points and validation. How we do it, not why. Go to overview

Situation

When this playbook applies.

An API is to be used by partners, mobile apps or several frontends. Unlike internal code, a public interface is a promise: changes affect external systems you don't control.

Objectives

  • The API remains stable and predictable for its consumers.
  • It can evolve without breaking existing integrations.
  • It is documented and usable without having to ask questions.

Typical risks

  • Breaking changes that silently break integrations.
  • Passing internal data models through to the outside — tight coupling.
  • Missing idempotency for repeated calls.
  • Unclear error and status semantics.
Preparation

Before we build.

  • Understand the consumers and their real use cases — rather than mirroring the internal structure.
  • Model resources and their relationships independently of the database.
  • Define the versioning and deprecation strategy before v1 ships.
Engineering approach

How we proceed.

01

API-first, as a contract

The interface is designed and documented first (for example as OpenAPI). The contract comes before the implementation.

02

Decouple from the outside

External representations are deliberately separated from internal models. Internal changes must not force the API to change.

03

Idempotency and clear semantics

Write operations are idempotent; status codes, error formats and pagination are consistent and documented.

04

Version additively

Changes are additive wherever possible. A breaking change means a new version with a clear deprecation period.

Decision checkpoints

Questions that need an answer.

  • Does the resource reflect the consumers' use case — or the internal table?

  • Is every write operation idempotent?

  • Is the change additive, or does it need a new version?

  • Is the behavior documented before it is implemented?

Validation

  • The documentation is sufficient to integrate without asking questions.
  • Contract tests verify the contract against the implementation.
  • Repeated calls don't produce a duplicate effect.

Common mistakes

  • Exposing internal data models one-to-one as the API.
  • Introducing versioning only after the fact.
  • Returning errors that are vague or inconsistent.
  • Rolling out breaking changes without a deprecation period.
Counter-check

When we deliberately take a different approach.

  • For purely internal communication between your own services, tighter coupling can be acceptable — there, the contract is cheaper to change.
  • Where clients need very different slices of the data, we consider GraphQL instead of strictly resource-oriented REST.

Engineering Method phases involved

Facing a similar challenge?

Playbooks show how we think. For your specific project, talk to our management — technical, no sales pitch.