API contracts that survive imperfect clients
Design explicit inputs, outputs, errors, compatibility rules, and duplicate handling across service boundaries.
On this page
The question for today
What you’ll understand
- Define syntactic and semantic parts of an API contract.
- Distinguish idempotency from identical responses or exactly-once execution.
- Budget validation and dependency time within a request deadline.
An API is a promise between independently changing components. Its contract includes more than a field list: callers need to know what values mean, which errors are recoverable, and what happens when requests are repeated. Clear contracts reduce accidental coupling and make failures explainable. This matters particularly when a model-serving API sits between users, billing, queues, and expensive computation.
Specify meaning as well as shape
A schema can say that a field is a number without saying whether it measures seconds, milliseconds, or a probability. Document units, bounds, required fields, nullability, and unknown-field behavior. For inference, define accepted input size and encoding, model identity, and output interpretation. A score is not automatically a calibrated probability. A well-formed response can still violate the domain meaning the caller relied on.
Validation belongs at a boundary where assumptions change. Reject malformed or unsupported input with useful, stable error information, while avoiding leaks of internal state or sensitive data. Authentication identifies a principal; authorization determines what that principal may do. Successful schema validation supplies neither. Describe these responsibilities explicitly instead of treating every failure as a generic server error or expecting generated client types to enforce runtime values.
Repeated requests need a defined effect
An idempotent operation has the same intended effect when applied repeatedly as when applied once. That does not require identical response bodies, and it does not guarantee that only one internal execution occurs. For a job-creation API, an application can define a client-supplied operation key and store its associated request and result. A retry with the same key can then refer to the same logical submission.
Such a policy needs details: key scope, retention duration, concurrent duplicates, and behavior when a key is reused with different content. Persisting the key separately from the effect can leave a failure gap, so the implementation needs an appropriate atomicity story. Do not advertise exactly-once business outcomes merely because a header exists. State which repeated effects the contract prevents and which failures still require reconciliation.
Compatibility is a behavioral agreement
Adding an optional field is often easier to accommodate than removing a required one, but compatibility depends on consumer behavior. A client that rejects unknown fields can break on an addition. A changed default, ordering, precision, or error code can break a consumer without changing the JSON shape. Contract tests should cover documented examples and critical invariants across producer and consumer versions rather than simply checking that a document parses.
Use an API description to make operations discoverable, then keep it consistent with running behavior. The lab isolates the load side of retries. Increase arrival rate while keeping service rate fixed and watch the fluid backlog. Compare this with the extra attempts in the equation above. This queue does not validate schemas, enforce deadlines, deduplicate operations, or generate retries automatically. The separate M/M/1 residence-time readout requires its stochastic assumptions; the fluid animation alone does not establish production latency.
Work it through
A retry-safe model job submission
A client submits a model job, loses the response, then retries. The agreed contract retains operation keys for 24 hours and rejects a reused key with different input.
The client assigns one operation key to the logical submission and keeps the same key on its retry. Generating a new key would describe a new logical operation under this contract.
The service compares the repeated request with the recorded request. If they agree, it returns the existing job identity; if they differ, it returns the documented conflict instead of silently changing the job.
Ensure the job record and duplicate record are created with suitable atomicity. Explain that a retry after the 24-hour retention window no longer has the same duplicate-prevention promise, and provide a reconciliation path for ambiguous cases.
The contract can prevent duplicate logical submissions within its stated scope. It does not imply exactly-once execution of every downstream task.
The living notebook
Explore the model
Interactive lab · queue
Retries still consume boundary capacity
Raise arrival rate λ to represent additional attempt load while holding service rate μ fixed. The fluid queue starts with four jobs. It does not generate retries or implement validation, authorization, and duplicate prevention.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forPreventing duplicate business effects does not make retry attempts free to process.
Pause & reason
Check your understanding
Your turn
Try it yourself
A service receives 800 logical requests per second. Exactly 10% make one additional attempt. Estimate attempt rate and explain one capacity implication.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Count original attempts and the additional retries separately.
Compare with the solution
There are 800 original attempts and 80 retries per second, giving 880 attempts per second. Even when deduplication prevents repeated business effects, retries still consume boundary and lookup capacity. Multiple retrying layers could amplify the load beyond this one-retry model.
Keep the idea
Take it with you
- A schema needs units, semantics, errors, and authorization rules around it.
- Idempotency is a scoped statement about intended effects.
- Compatibility and retries must be tested as behavior across versions.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.