UgurKeser.art

Designing an API boundary before the second product arrives

An API boundary becomes important before a second product depends on it.

Uğur Keser4 min read

An API boundary becomes important before a second product depends on it. If the first consumer’s screens, names and assumptions define the entire interface, another consumer may require exceptions throughout the system. The aim is not to predict every future use case; it is to make the current business capability explicit enough that another caller can understand it.

This article proposes a design review for an early API. It does not describe a deployed shared platform across the projects listed on this site.

Name the business operation

Start with a task such as submitting an audit request, reading a product record or retrieving an order status. Avoid defining the interface solely around one page’s layout. The business operation should retain meaning if the interface changes from a web page to another client.

Identify the owner of each field. A product may display a derived status without being authorized to change the underlying record. Clear ownership prevents two consumers from writing competing versions of the same truth.

Write the contract in plain language first

Contract area Question to answer
Identity How are resources and callers identified?
Input Which fields are required, optional or invalid?
Authorization Which caller can access which scope?
Outcome What does success guarantee?
Failure Which errors are retryable or require correction?
Concurrency What happens if the record changes during the request?
Compatibility How can the contract evolve without silent breakage?

A success response should not promise more than the system has completed. If work is queued, return a state that reflects that and provide a way to observe completion. A request accepted for processing is different from a finished report.

Keep tenant and user boundaries enforceable

Every operation should apply the appropriate caller context and resource scope. Do not rely on a client-supplied label alone to determine which customer’s data is accessible. Authorization checks belong on the service side for every relevant request.

Similarly, error messages should be useful without revealing unrelated records or implementation secrets. A second product should not gain broader access merely because it shares infrastructure with the first. Shared code and shared permissions are separate decisions.

Design retries and duplicate delivery

Network failures can leave the caller uncertain whether an operation completed. Define how a repeated request is recognized and how the caller reconciles an unknown outcome. Where an idempotency mechanism is used, document its scope and retention behavior.

Stripe’s idempotent-request documentation is one concrete example of an API that preserves a result for a repeated key under defined conditions. The lesson for a new API is to specify its own behavior explicitly rather than assuming every provider handles retries identically.

Separate domain data from presentation

Return stable business values and identifiers, with clear units and timestamps. Let each consumer decide how to present them within its own language and interface. If the service returns a ready-made display sentence, consider whether that sentence can remain correct across languages and contexts.

This separation does not forbid convenient fields. It asks which information is authoritative and which is derived presentation. Documenting that distinction reduces accidental dependencies on formatting details.

Introduce a second consumer as a test

A small internal client or controlled prototype can reveal assumptions hidden in the first interface. Use it to exercise the same contract, not a privileged shortcut. Check errors, pagination where needed, incomplete states and permission boundaries as well as successful retrieval.

The build-versus-integrate guide helps decide which capability belongs behind the boundary. The integration dependency guide addresses ongoing ownership. A good early API remains modest in scope while making identity, authority and outcomes difficult to misunderstand.