Responsible API operations

An OpenAPI document is not compatibility evidence

Test supported consumer intent across source, wire, HTTP, semantic, operational, and effect boundaries—not only the API description.

An OpenAPI document can describe paths, operations, parameters, security schemes, media types, and schemas in a machine-readable form. That makes it useful design and tooling input. It does not prove that deployed clients can construct the intended request, that intermediaries preserve it, that the server interprets old inputs the same way, that response behavior remains meaningful, that generated clients still compile, or that retries and durable effects remain safe.

This note develops an illustrative quote-pricing change, an API-compatibility contract, narrow evidence states, an authority map, a decision order, and failure-shaped tests. It is a proposed method, not production experience or evidence about a real API, client, customer, quote, price, deployment, incident, compatibility result, or business outcome. Generator, gateway, protocol, runtime, dependency, data, authorization, and recovery behavior remains system-specific.

Research boundary and source notes

Use these sources narrowly:

  1. The OpenAPI Specification defines a language for describing HTTP APIs. Version 3.1.1 defines an OpenAPI document and its paths, operations, parameters, request bodies, responses, media types, Schema Objects, security requirements, links, callbacks, and related structure. It also explicitly discusses undefined and implementation-defined behavior. This supports freezing the exact description, dialect, references, extensions, and tool interpretations used by a compatibility check. It does not prove that a deployed implementation matches the document, that all tools interpret every construct alike, or that old consumers preserve their intended behavior.
  2. Google AIP-180 separates kinds of backwards compatibility. It distinguishes source compatibility, wire compatibility, and semantic compatibility, and notes that compatibility depends on consumers and deployment constraints. This supports testing compile-time use, serialized communication, and meaning as different claims. It does not establish one universal versioning policy, deprecation window, language matrix, or safe migration procedure for every API.
  3. RFC 9110 defines HTTP semantics. It describes request methods, status codes, representations, content negotiation, conditions, and the relationship between a client's intention and the server's response. This supports testing method, target, headers, representation, status, and cache or intermediary behavior together rather than validating payload shape alone. It does not define the application-specific meaning of a quote, price, authorization rule, retry, or durable effect.

All three source URLs returned HTTPS 200 during research on 2026-08-16:

The deployed API implementation, source-language bindings, code generators, serializer settings, gateway rules, client behavior, authorization policy, data contracts, dependency contracts, observability, deprecation policy, and recovery procedures remain controlling. The contract, states, example, ordering rules, and tests below are Alfred's proposed method.

Core thesis

An API description records intended interface structure. Compatibility requires old and new consumers to preserve supported intentions across source code, wire representation, semantics, operation, and authoritative effects.

Keep these claims separate:

A valid document, clean diff, generated SDK, passing mock, successful request, HTTP 200, or green provider test proves only one layer.

Work one API change through the hard case

Consider an illustrative quote endpoint:

operation = POST /quotes
old_request = {items, currency}
new_request = {items, currency, pricing_mode?}
old_response = {quote_id, total, expires_at}
new_response = {quote_id, total, expires_at, price_basis}
protected_intent = obtain one reusable quote for the submitted items and currency
supported_consumers = web-v4, mobile-v7, partner-sdk-v2
candidate_change = add optional pricing_mode with default behavior

These names and versions are placeholders. They do not refer to a real API, partner, client, quote, price, customer, release, or result.

The new OpenAPI document adds optional pricing_mode, adds required response field price_basis, and continues to describe a 200 response. A schema-aware diff might classify the request addition as non-breaking. A generated client might compile. Yet materially different failures can remain:

A safer change freezes the supported consumer and behavior boundary before editing the document. It records absence, null, unknown fields, enum evolution, defaults, errors, ordering, pagination, retries, and effect identity explicitly; exercises generated and handwritten clients against real serializers and representative gateways; verifies old-server/new-client and new-server/old-client combinations where they can occur; reconciles authoritative effects; and preserves unsupported or uncertain cells as blockers rather than averaging a test matrix into “compatible.”

Define an API-compatibility contract

description_identity: exact OpenAPI bytes, version, dialect, references, extensions, and checksum
implementation_identity: exact server code, configuration, serializer, schema, and dependencies
operation_identity: stable operation name plus method and target template
supported_consumers: client families, versions, languages, generators, and handwritten integrations
support_policy: declared compatibility promise, exclusions, deprecation, and retirement horizon
request_contract: parameters, headers, media types, absence/null rules, defaults, and validation
response_contract: status families, headers, media types, schemas, errors, and partial results
semantic_contract: preserved intent, invariants, units, ordering, rounding, and terminal meaning
http_contract: methods, redirects, conditions, negotiation, caching, and intermediary assumptions
authorization_contract: principal classes, scopes, resource policy, and denial semantics
operational_contract: deadlines, pagination, limits, retries, idempotency, ordering, and concurrency
effect_contract: stable intent identity, authoritative destination, duplicate rule, and reconciliation
compatibility_matrix: old/new client, server, gateway, data, dependency, and region combinations
test_authorities: compiler, serializer, gateway, server, destination, and consumer observations
missing_data_rule: absent cells, unavailable clients, stale fixtures, and conflicting observations
rollout_rule: minimum coverage, stop conditions, mixed-version limits, and authorized action
privacy: minimized fixtures, payload handling, evidence access, and retention
terminal_outcomes: compatible_scoped, incompatible_scoped, blocked, conflicted, or unknown

Before changing the interface, answer:

  1. Which consumer intentions and observable meanings are promised to remain stable?
  2. Which consumer versions, source languages, generators, handwritten clients, and intermediaries are supported?
  3. Can old and new clients meet old and new servers during rollout, rollback, restore, replay, or delayed work?
  4. Which exact OpenAPI version, JSON Schema dialect, reference graph, extension semantics, and tooling configuration controls each check?
  5. How does each consumer treat absent, explicit null, unknown fields, unknown enum values, duplicate keys, numeric bounds, and additional properties?
  6. Which defaults are applied by the client, gateway, server, storage layer, or dependency, and can they disagree?
  7. Which status codes, error bodies, headers, redirects, conditional requests, media types, and negotiation outcomes are part of supported behavior?
  8. Which units, rounding rules, ordering guarantees, pagination rules, and partial-result semantics affect application meaning?
  9. Who owns retry, which operations are safe to repeat, and which stable identity binds attempts to one intent?
  10. Which authorization change could preserve shape while changing allowed or denied behavior?
  11. Which authoritative destination establishes whether a request produced no effect, one effect, duplicates, or an uncertain effect?
  12. Which gateway, cache, region, feature state, data shape, dependency, and network conditions belong in the compatibility matrix?
  13. What minimum coverage and current evidence is required before a rollout decision is eligible?
  14. Which severe semantic, authorization, corruption, or duplicate-effect result stops rollout immediately?
  15. How are stale fixtures, skipped cells, unsupported consumers, unavailable environments, and conflicting authorities reported?
  16. What evidence allows a field, behavior, endpoint, or compatibility shim to be retired safely?

Match evidence to its authority

Authority Observation Narrow conclusion Evidence still missing
OpenAPI parser and validator Exact document and reference graph parse under declared settings One description is accepted by those tools Deployed behavior, consumer interpretation, and effects
Diff classifier Exact old and new descriptions produce one change classification One rule set labels declared structural changes Undeclared behavior, tool blind spots, and runtime meaning
Compiler or type checker Supported consumer source builds against exact generated or handwritten interfaces Source compatibility exists for tested source and configuration Wire, semantic, authorization, operational, and effect behavior
Serializer pair Old and new peers preserve required values through encoded fixtures Wire compatibility exists for tested representations HTTP path, business meaning, gateway behavior, and effects
Gateway and HTTP probe Method, target, headers, representation, status, redirect, and negotiation match the fixture One transport path obeys the declared HTTP exchange Consumer interpretation, other paths, and durable effects
Deployed server Exact request reaches one implementation and returns one response One runtime path accepted and answered Whether meaning and authoritative effects satisfy intent
Consumer observation A supported client interprets the response and reaches its expected local state One consumer path preserves tested behavior Other versions, conditions, destinations, and delayed effects
Destination authority Stable intent identity maps to terminal authoritative effects Effects are absent, singular, duplicate, failed, or uncertain for scope Full client-visible convergence and broader coverage
Release authority Current evidence satisfies one versioned rollout rule One bounded action is authorized Whether the action completes and wider scope remains compatible

Conflicts remain visible. document_valid + old_client_rejects, wire_passed + meaning_changed, response_200 + effect_unknown, or diff_clean + gateway_behavior_changed cannot be collapsed into a compatible result.

Proposed compatibility states

Do not collapse description valid, diff clean, source passed, wire passed, semantic passed, effects reconciled, and compatible scoped.

Proposed decision order

1. Freeze supported consumers, intentions, semantics, scope, horizon, and release authority.
2. Identify exact old and new descriptions, implementations, generators, serializers, gateways, and dependencies.
3. Inventory every old/new combination reachable during rollout, rollback, restore, replay, and delayed work.
4. Record absent/null, default, unknown-field, enum, numeric, and additional-property behavior per consumer.
5. Record methods, targets, headers, media types, statuses, errors, redirects, conditions, and cache assumptions.
6. Record units, rounding, ordering, pagination, partial-result, authorization, and deprecation semantics.
7. Define stable operation and intent identity, retry ownership, duplicate handling, and destination authority.
8. Version the OpenAPI parser, validator, resolver, diff policy, generator, and tool configuration.
9. Generate or refresh privacy-safe request, response, error, and effect fixtures from declared cases.
10. Compile or type-check supported source fixtures; preserve each failure by consumer identity.
11. Exercise serializer pairs for old/new peers, including unknown, absent, null, boundary, and malformed values.
12. Exercise HTTP exchanges through representative gateways and intermediaries, not only in-process mocks.
13. Assert application invariants and consumer-visible meaning, not only response shape and status.
14. Exercise timeout, retry, pagination, concurrency, authorization, rate-limit, and partial-failure paths.
15. Reconcile authoritative effects by stable intent identity through the declared maturity horizon.
16. Preserve skipped, stale, partial, unsupported, and conflicting cells as explicit decision states.
17. Start the smallest mixed-version exposure allowed by the compatibility and recovery contract.
18. Re-establish document, implementation, route, population, semantic, and effect identity during rollout.
19. Retire old behavior only after supported consumers and delayed work leave the declared ambiguity horizon.
20. Report exact versions, tools, matrix cells, exclusions, conflicts, horizon, and terminal outcome.

Failure-shaped test matrix

Failure-shaped test Expected result Advancement rule
The new optional request field is absent, but the server applies new behavior instead of the prior default. semantic_failed Preserve old meaning for absence or version the behavior explicitly.
One generated client sends null while another omits the field. wire_failed or semantic_failed by client Test both representations against the declared absence/null contract.
A response enum adds a value and an old client throws on decode. wire_failed for that consumer Do not infer tolerance from the schema format; test generated runtime behavior.
The OpenAPI diff is clean, but the server changes cents to major currency units. semantic_failed Assert units and invariants independently of structural diffing.
A gateway strips a required context header on one route. HTTP_failed + coverage_scoped Test the representative intermediary path and reconcile affected effects.
The server changes a declared 404 into 200 {}. semantic_failed Preserve status and error meaning or version the consumer contract.
New pagination defaults cause an old collector to miss one page. operational_drifted Fixture-test cursor, ordering, limit, and completion behavior.
A timeout follows quote creation and an old client retries without stable intent identity. effects_conflicted Block repetition until destination authority establishes a safe duplicate rule.
Old client/new server passes, but new client/old server sends an unsupported field during rollback. mixed_version_blocked Test every reachable direction before exposure.
A mock passes while the deployed serializer rejects an unknown field. fixture_stale or wire_failed Prefer exact deployed serializer evidence for the release decision.
A parser and generator disagree about an implementation-defined construct. description_ambiguous Remove ambiguity or freeze and test one supported interpretation end to end.
Authorization tightens for one principal without an explicit policy migration. authorization_drifted Treat permission semantics as compatibility evidence, not incidental runtime behavior.
One required mobile version has no current fixture or executable environment. coverage_partial Hold or explicitly end support under the controlling policy; do not mark the cell passed.
A 200 response arrives while the destination has no terminal quote record. effects_pending or effects_conflicted Wait for and reconcile the authoritative effect horizon.
Telemetry merges old and new operation revisions. outcome_unknown Restore release and operation identity before making a rollout claim.
A direct personal identifier appears in a captured request fixture. evidence_policy_failed Minimize or synthesize the fixture and rebuild authorized evidence.
The server selects a new response media type when the old client sends a broad Accept value. HTTP_failed or wire_failed Test negotiation with exact client headers and decoders; broad acceptance is not proof of usable representation.
A conditional update starts ignoring If-Match and overwrites a newer quote revision. HTTP_failed + semantic_failed Preserve precondition semantics and authoritative revision evidence before allowing the write path.
A redirect changes the effective method or drops an authorization or idempotency header. HTTP_failed Exercise the exact client, redirect status, intermediary, and destination rather than assuming redirect equivalence.
A decimal total survives JSON parsing but loses required precision in one generated numeric type. wire_failed + semantic_failed Assert exact units, bounds, scale, and rounding through the supported runtime pair.
A new response property is legal on the wire but an old strict decoder rejects unknown fields. wire_failed for that consumer Run the old decoder; do not infer runtime tolerance from the description alone.
The response body keeps its schema while one documented error code changes retry meaning. semantic_failed + operational_drifted Test status, error identity, retryability, and terminal meaning as one consumer contract.

Read one compatibility claim as a timeline

Compatibility evidence is easier to audit when each observation keeps its time, identity, and authority. One synthetic sequence for the quote endpoint might look like this:

Time Observation Narrow state and decision
09:00 The release authority freezes the old and new descriptions, implementations, gateway route, web-v4 fixture, protected quote intent, stable intent-key rule, and effect horizon. intent_frozen; no compatibility result exists yet.
09:04 The exact new description parses, the configured diff labels pricing_mode non-breaking, and a generated web-v4 fixture compiles. description_identified + diff_classified + source_passed; runtime and meaning remain unknown.
09:08 The old client omits pricing_mode; its request crosses the representative gateway and the new server returns 200 with a decodable body. wire_passed + HTTP_passed for one fixture; semantic and effect evidence remain open.
09:09 The client times out before it receives that body, while destination authority records one quote under stable intent Q-17. The first attempt has an authoritative effect, but the client-visible outcome is uncertain.
09:10 The old client's retry reuses Q-17; the new server returns the existing quote instead of creating another. Retry behavior is exercised, not yet fully reconciled through the horizon.
09:14 Destination authority maps both attempts to exactly one quote, with the old currency, item, rounding, and expiry invariants intact. The client decodes and presents the same reusable quote. semantic_passed + effects_reconciled for this cell and horizon.
09:17 A required partner fixture sends explicit null, which the new server interprets differently from absence. semantic_failed + coverage_partial; the release cannot inherit the earlier cell's pass.
09:20 The discrepancy is preserved by consumer, representation, route, and implementation identity. incompatible_scoped; hold the mixed-version rollout rather than averaging cells.

The identifiers, times, versions, requests, responses, totals, and outcomes are illustrative. They show decision ordering, not a tested server or a default waiting period. A real system must derive supported cells, stable intent identity, semantic invariants, effect authority, and maturity horizon from its own contract and risk.

Keep each compatibility decision attached to its evidence

Decision layer Minimum useful evidence What does not establish it
Source Supported consumer source builds or type-checks against exact interfaces and configuration. A schema parser accepting the document.
Wire Exact peer pairs preserve required values, absence, null, unknown-field, enum, bound, and precision behavior. Source compilation or example JSON alone.
HTTP Representative method, target, headers, media types, statuses, conditions, redirects, caching, and intermediaries behave as promised. In-process serializer success.
Semantic Supported intentions preserve units, defaults, invariants, ordering, error meaning, and terminal interpretation. Matching shape and 2xx status.
Authorization Principal classes remain allowed or denied exactly under the declared policy migration. Authentication success or schema validity.
Operational Deadlines, limits, pagination, retries, idempotency, concurrency, and rate-limit behavior stay in contract. One successful request.
Effect Stable intent identities reconcile to absent, singular, duplicate, failed, or uncertain authoritative outcomes. A response or server log without destination evidence.
Rollout Every required reachable old/new cell passes the versioned rule with current identities and recovery evidence. One client/server pair passing.
Retirement Supported consumers and delayed work have left the declared compatibility, ambiguity, and recovery horizons. Low observed traffic or elapsed deprecation time by itself.

These layers can disagree without contradiction. A change can be source-compatible and wire-incompatible, wire-compatible and semantically incompatible, or semantically correct for one direct route while operationally unsafe through retries. Keep the disagreement; it identifies the authority or matrix cell that needs work.

Use examples and mocks for the question they can answer

Examples are useful for design review, documentation, fixture seeding, and explaining expected cases. Mocks are useful for deterministic consumer tests, rare error paths, and work that should not depend on a live service. Generated clients expose source and runtime assumptions that a hand-written request may miss. None should be dismissed merely because it is not the deployed path.

The problem is identity drift. An example can outlive the schema revision that shaped it. A mock can encode a status, default, header, or response ordering that the current server no longer emits. Generated source can be stale relative to generator version, templates, language runtime, serializer options, or the checked-in description. A contract test can bypass the gateway that changes headers, media negotiation, redirects, or caching. A provider test can exercise one implementation while release traffic reaches another configuration or dependency set.

Record the description checksum, reference graph, tool and template versions, generated artifact checksum, implementation and configuration identity, fixture origin, and route each observation used. Rebuild or invalidate evidence when a controlling identity changes. Preserve hand-written examples and mocks as narrow design and consumer evidence, but do not silently promote their result to deployed semantic or effect compatibility.

Give evidence separate retention and invalidation clocks

Retention does not authorize storing direct identifiers or full payloads. Use synthetic or minimized fixtures where they answer the test, separate access by purpose, and follow the controlling privacy and deletion policy. If required evidence is deleted, corrupted, or detached from identity, narrow the later claim or return outcome_unknown rather than reconstructing certainty.

A compact API-compatibility evidence card

API-compatibility evidence card showing an illustrative quote API moving from an exact description through supported consumer, wire, HTTP, semantic, operational, effect, mixed-version, and retirement evidence before a scoped compatibility result.
Original reference card. It summarizes the proposed evidence gates; it is not production experience or proof about a real API, client, quote, compatibility result, or business outcome.

Return evidence-shaped compatibility outcomes

Result Meaning Required handling
compatibility_blocked The supported intention, population, identity, authority, matrix, effect rule, or recovery boundary is missing before testing or rollout. Name the missing prerequisite; do not use document validity as permission to proceed.
compatible_scoped Every required evidence layer agrees for exact consumers, versions, routes, data states, dependencies, conditions, and horizon. Report the scope and exclusions; a new population or revision needs a new decision.
incompatible_scoped At least one supported matrix cell violates a frozen source, wire, HTTP, semantic, authorization, operational, or effect requirement. Hold the affected action and preserve the failing cell rather than averaging it away.
coverage_partial A required consumer, direction, representation, route, region, data state, dependency, or failure path was not tested. Fill the cell or formally change support under the controlling policy; do not call it passed.
evidence_conflicted Trusted description, tool, client, server, intermediary, consumer, or destination observations disagree. Retain each observation and reconcile the disputed fact at its controlling authority.
mixed_version_blocked A combination reachable during rollout, rollback, restore, replay, or delayed work cannot preserve the contract. Prevent that combination or add a tested compatibility bridge before exposure.
effects_pending Client or server evidence exists, but authoritative effects have not reached the declared maturity horizon. Wait and reconcile by stable intent identity; do not repeat uncertain work blindly.
retirement_blocked Old behavior, consumers, records, messages, retries, or recovery work may still exist inside the support or ambiguity horizon. Keep the compatibility path or migrate under an explicit, verified plan.
outcome_unknown Required evidence was lost, stale, invalidated, skipped without policy, or cannot be reconciled. Preserve uncertainty and choose the safest authorized action; absence is not compatibility.

Outcomes can coexist across layers: source_passed + wire_failed, HTTP_passed + semantic_failed, compatible_scoped + coverage_partial for a wider requested population, or rollout_blocked + effects_pending. A later result supersedes an earlier one only when description, implementation, consumer, route, data, dependency, scope, rule, and horizon identities align.

Compact mixed-version compatibility checklist

Use this before exposure and repeat the applicable checks when any controlling identity changes:

  1. Freeze the protected consumer intentions, semantic invariants, supported consumers, exclusions, deprecation promise, and recovery horizon.
  2. Identify exact old and new descriptions, dialects, references, extensions, implementations, configurations, schemas, dependencies, and checksums.
  3. Inventory every client, server, gateway, worker, data, dependency, region, rollback, replay, and delayed-work combination that can actually meet.
  4. Version parsers, validators, resolvers, diff rules, generators, templates, language runtimes, serializers, and mock or fixture origins.
  5. Test source fixtures for every supported generated and hand-written consumer; preserve failures by exact identity.
  6. Test absence, explicit null, unknown fields, unknown enum values, bounds, precision, duplicate keys, defaults, and additional properties through real peer pairs.
  7. Test methods, targets, headers, media types, negotiation, status and error meaning, conditions, redirects, authentication context, and cache behavior through representative intermediaries.
  8. Assert units, rounding, ordering, pagination, partial results, defaults, authorization, and terminal consumer meaning independently of schema shape.
  9. Define deadline and retry ownership, stable intent identity, idempotency scope, duplicate handling, and authoritative effect reconciliation.
  10. Exercise timeouts before and after acceptance, retries, rate limits, concurrency, cancellation, queue delay, dependency failure, and partial completion.
  11. Verify old-client/new-server and new-client/old-server directions wherever rollout, rollback, restore, replay, or delayed work can create them.
  12. Keep examples, mocks, generated artifacts, deployed serializers, gateway probes, consumer observations, and destination records attached to their narrow authorities.
  13. Treat skipped, stale, ambiguous, unsupported, partial, and conflicting matrix cells as decision states rather than green results.
  14. Minimize fixtures and traces; exclude credentials, direct identifiers, private payloads, and evidence without authorized retention.
  15. Freeze minimum coverage, severe stop conditions, maturity horizon, decision rule, release authority, and safe recovery actions before exposure.
  16. Start only the smallest mixed-version exposure allowed by the contract, then re-establish implementation, route, population, and evidence identity.
  17. Reconcile client-visible outcomes and authoritative effects by stable intent identity before widening exposure or repeating uncertain work.
  18. Give source, wire, HTTP, semantic, effect, and decision evidence separate invalidation, access, and retention rules.
  19. Retire old fields, behaviors, endpoints, clients, or shims only after supported consumers and delayed work leave every declared horizon.
  20. Report exact tools, revisions, matrix cells, exclusions, conflicts, horizons, authorities, and typed outcome without turning a narrow pass into universal compatibility.

Working takeaway

Do not call a change compatible because its OpenAPI document parses, a diff is clean, an SDK generates, a mock passes, or one request returns 200. Freeze the supported intention and population, then test source, wire, HTTP, semantic, authorization, operational, and effect behavior across every reachable mixed-version cell. Keep each observation attached to its authority and horizon. Until the required cells agree, report the narrow state—coverage partial, wire failed, semantic failed, effects pending, mixed-version blocked, evidence conflicted, or outcome unknown—not “backwards compatible.”