api-contract · diff

git:20260525.cf1dde7 to git:20260531.ac0b4b8

76 added, 100 removed. Audit A to A.

---
name: api-contract
- description: Use when generating an OpenAPI 3.1 API contract from requirements, user stories, or domain models. Applies 138 RESTful API rules as hard constraints to produce complete, validated YAML specs ready for code gen, test gen, mocks, and SDKs. Activate for tasks involving API design, REST contract authoring, or OpenAPI spec creation.
+ description: Use when generating an OpenAPI 3.1 API contract from requirements, user stories, or domain models. Applies a pluggable API standard (Zalando by default) as hard constraints to produce complete, validated YAML specs ready for code gen, test gen, mocks, and SDKs. Activate for tasks involving API design, REST contract authoring, or OpenAPI spec creation.
---
# API Contract Generation
- > Derived from the [Zalando RESTful API Guidelines](https://opensource.zalando.com/restful-api-guidelines/) (CC-BY-4.0, Zalando SE).
- > 138 of 143 rules apply. 5 Zalando-internal rules excluded: #183, #184, #223, #224, #233.
+ > **Standard-driven.** This skill carries the API-design *method*; the rules it
+ > enforces are *data* supplied by the **active standard**. The bundled default
+ > is Zalando (`references/standards-manifest-zalando.yaml`). An organisation can
+ > plug in its own standard as a base+delta bundle without forking this skill —
+ > see [references/standards-authoring.md](references/standards-authoring.md).
## Your Role
- You are an API contract author inside an SDLC pipeline, following the API-first principle [#100].
+ You are an API contract author inside an SDLC pipeline, following the active standard's API-first principle.
**Inputs you receive:** user stories, domain models, plain-English requirements, existing partial specs.
**Output you produce:** a single, complete, valid OpenAPI 3.1 YAML document that downstream tooling (code generators, test generators, mock servers, SDK builders) can consume without modification.
- The Zalando rules below are **hard constraint rails** -- every MUST/MUST NOT is non-negotiable. SHOULD rules are followed unless you document the deviation inline with a rationale comment.
-
- ## Design Method
-
- Follow these phases in order. Do not skip ahead.
-
- ### Phase 1 -- Understand & Model
-
- 1. **Parse requirements.** Extract resources, relationships, operations, and business invariants from the input. For complex APIs, plan an API user manual [#102].
- 2. **Identify the domain model.** Define useful resources with clear identity and lifecycle [#140]. Name resources using domain language [#142]. Model complete business processes [#139]. Map relationships (1:1, 1:N, M:N) to decide nesting depth (max 3 segments after the root) [#147].
- 3. **Choose audience.** Tag `x-audience` [#219] -- `external-public`, `external-partner`, or `company-internal`.
- 4. **Assign API meta.** Populate `info.title`, `info.description`, `info.version` (semantic versioning) [#218][#116], `info.contact`, and `x-api-id` (UUID) [#215].
-
- ### Phase 2 -- Design URLs & Methods
+ ## The active standard
- 1. **Build resource paths.** Use kebab-case [#129], plural nouns [#134], no verbs [#141], no `/api` prefix [#135], normalized (no trailing slash, no duplicated slashes) [#136]. Use URL-friendly resource IDs [#228].
- 2. **Map operations to HTTP methods.** Follow method semantics exactly [#148][#149]. Use idempotent POST/PATCH via `Idempotency-Key` where needed [#229]. See [references/http-methods-and-status-codes.md](references/http-methods-and-status-codes.md).
- 3. **Define query parameters.** Use snake_case [#130], conventional names (`q`, `sort`, `cursor`, `limit`, `fields`, `embed`) [#137]. Paginate all list endpoints [#159], prefer cursor-based [#160]. See [references/pagination-and-filtering.md](references/pagination-and-filtering.md).
+ Before authoring, resolve the **active standard** — the data this method applies:
- ### Phase 3 -- Design Representations
+ 1. **Read the standard manifest.** The default is `references/standards-manifest-zalando.yaml`. If your organisation installed a custom standard (a bundle that `extends` the base, delivered via `adapt-to-project`'s `.upstream` companion-merge), read that instead.
+ 2. **Load rule files per phase.** The manifest names the standard's rule files (grouped by the phases below), its quality-gate checklist, and any reusable schema components. Load the rule file for each phase as you reach it.
+ 3. **Resolve base + delta by reading.** If the manifest `extends` a base, apply the base's rules first, then the delta: a rule the delta sets to `false` is disabled; rules under `adds` are additional house rules. Nothing parses the manifest for you — you resolve it by reading.
- 1. **JSON payloads.** Request and response bodies MUST be JSON [#167] with top-level objects (no bare arrays) [#110]. JSON-derived media types are permitted: `application/merge-patch+json` for PATCH [#148], `application/problem+json` for errors [#176].
- 2. **Property naming.** `snake_case` [#118], no null booleans [#122]. Pluralize array names [#120]. Use `_at` suffix for date-time, `_date` for date-only [#235]. Follow common field names [#174].
- 3. **Data formats.** Use standard `format` values [#238] and explicit number formats (`int32`, `int64`, `decimal`) [#171]. ISO 8601 for date-time [#169]. ISO 3166/639/4217 for country/language/currency [#170]. See [references/data-formats-and-common-objects.md](references/data-formats-and-common-objects.md).
- 4. **Null handling.** Define null semantics clearly [#123]. Never return null for booleans [#122] or empty arrays [#124].
- 5. **Reusable objects.** Use the standard Money [#173] and Address [#249] objects from `#/components/schemas/`. Use a single schema for read and write where possible [#252].
- 6. **Enumerations.** Use UPPER_SNAKE_CASE enum values [#240]. For evolvable value sets, use `examples` keyword (not closed `enum`) to signal open-ended values [#112].
+ Every MUST / MUST-NOT in the active standard is a non-negotiable rail. SHOULD rules are followed unless you document the deviation inline with a rationale comment. The rule numbers and the specific conventions — casing, path grammar, pagination policy, error format, versioning strategy — all come from the active standard; this method does not hardcode them.
- ### Phase 4 -- Error Handling & Status Codes
+ ## Design Method
- 1. **Specify success and error responses** for every operation [#151]. Use official HTTP status codes only [#243].
- 2. **Use RFC 9457 Problem Detail** (`application/problem+json`) for all error responses [#176]. Never expose stack traces [#177].
- 3. **Batch operations** return `207 Multi-Status` [#152]. Rate-limited endpoints return `429` with `Retry-After` [#153].
- 4. See [references/http-methods-and-status-codes.md](references/http-methods-and-status-codes.md) for the full method-to-status-code matrix.
+ Follow these phases in order. Do not skip ahead. For each phase, load the active standard's rule file for that category (named in the manifest) and apply its rules.
- ### Phase 5 -- Security & Headers
+ ### Phase 1 — Understand & Model
- 1. **Secure every endpoint** with a `security` scheme [#104]. Define OAuth2 flows and scopes [#105] using `<api-name>.<resource>.<access-level>` naming [#225].
- 2. **Support gzip** via `Accept-Encoding` [#156].
- 3. **Document caching** behavior with `Cache-Control` headers where applicable [#227].
- 4. **Support partial responses** via `fields` query parameter for large resources [#157].
+ 1. **Parse requirements.** Extract resources, relationships, operations, and business invariants from the input.
+ 2. **Identify the domain model.** Define useful resources with clear identity and lifecycle, name them in domain language, model complete business processes, and map relationships (1:1, 1:N, M:N) to decide nesting depth — within the active standard's limits.
+ 3. **Choose audience.** Tag the API's audience as the active standard requires (e.g. external-public / external-partner / company-internal).
+ 4. **Assign API meta.** Populate `info` (title, description, version), contact, and any standard-required identifiers (e.g. an API id / audience extension).
- ### Phase 6 -- Compatibility & Extensibility
+ ### Phase 2 — Design URLs & Methods
- 1. **Do not introduce breaking changes** to published APIs [#106]. Follow the compatible extension rules [#107].
- 2. **Design for tolerant readers** [#108] and **open for extension** [#111].
- 3. **Version via media types** if needed [#114]. Never version in the URL [#115].
- 4. See [references/compatibility-and-versioning.md](references/compatibility-and-versioning.md).
+ 1. **Build resource paths** following the active standard's naming and structure rules (casing, pluralisation, verb policy, prefix policy, normalisation, depth limits).
+ 2. **Map operations to HTTP methods** following the standard's method-semantics and idempotency rules. Load the methods/status rule file.
+ 3. **Define query parameters** using the standard's naming and conventional-parameter rules; paginate list endpoints as the standard requires. Load the pagination/filtering rule file.
- ### Phase 7 -- Hypermedia & Events
+ ### Phase 3 — Design Representations
- 1. **Target REST maturity level 2** (HTTP verbs + status codes) [#162]. Add hypertext controls for navigation [#164] using absolute URIs [#217].
- 2. **If the domain includes asynchronous events,** treat event schemas as API contracts [#194] and apply event rules. See [references/events.md](references/events.md) for categories [#198], metadata [#247], data change events [#202], and backward compatibility [#209].
- 3. See [references/hypermedia-and-performance.md](references/hypermedia-and-performance.md).
+ 1. **Payloads & media types** per the standard's representation rules (body format, top-level shape, permitted JSON-derived media types).
+ 2. **Property naming** per the standard (casing, array pluralisation, date/time suffixes, common field names).
+ 3. **Data formats** per the standard (standard `format` values, number formats, date/time and country/language/currency encodings). Load the data-formats rule file.
+ 4. **Null handling** per the standard.
+ 5. **Reusable objects.** Use the standard's reusable schema components (named in the manifest — e.g. Money, Problem) where applicable.
+ 6. **Enumerations** per the standard (value casing; open vs. closed enums for evolvable value sets).
- ## Quality Gates
+ ### Phase 4 — Error Handling & Status Codes
- Before finalizing the output, verify every item. A single failure means the spec is not ready.
+ 1. **Specify success and error responses** for every operation, using only official HTTP status codes as the standard requires.
+ 2. **Use the standard's error format** for all error responses; never expose stack traces.
+ 3. **Batch / rate-limit** semantics per the standard. Load the methods/status rule file for the full matrix.
- ### Structural Validity
+ ### Phase 5 — Security & Headers
- - [ ] Valid OpenAPI 3.1 YAML (parseable, no `$ref` errors)
- - [ ] `info.title`, `info.description`, `info.version`, `info.contact` present [#218]
- - [ ] `x-api-id` is a UUID [#215]
- - [ ] `x-audience` is set [#219]
- - [ ] Semantic version format in `info.version` [#116]
+ 1. **Secure every endpoint** with a `security` scheme; define auth flows and scope naming per the standard.
+ 2. **Encoding, caching, partial responses** per the standard where applicable.
- ### Security
+ ### Phase 6 — Compatibility & Extensibility
- - [ ] Every operation has a `security` entry [#104]
- - [ ] OAuth2 scopes defined and assigned [#105]
- - [ ] Scope names follow `<api>.<resource>.<access>` [#225]
+ 1. **Avoid breaking changes** to published APIs; follow the standard's compatible-extension and tolerant-reader rules.
+ 2. **Versioning** per the standard's strategy. Load the compatibility/versioning rule file.
- ### URL Design
+ ### Phase 7 — Hypermedia & Events
- - [ ] All paths kebab-case, plural, verb-free [#129][#134][#141]
- - [ ] No `/api` prefix [#135]
- - [ ] Sub-resource depth at most 3 [#147]
- - [ ] Query parameters are snake_case [#130]
+ 1. **REST maturity / hypermedia** per the standard. Load the hypermedia/performance rule file.
+ 2. **If the domain includes asynchronous events,** treat event schemas as API contracts and apply the standard's event rules. Load the events rule file.
- ### Representations
+ ## Design discipline
- - [ ] All request/response bodies are JSON-based (`application/json`, `application/merge-patch+json`, or `application/problem+json`) [#167]
- - [ ] All top-level responses are objects (no bare arrays) [#110]
- - [ ] Properties are snake_case [#118]
- - [ ] Boolean properties are non-nullable [#122]
- - [ ] Array properties are pluralized [#120] and non-null when empty [#124]
- - [ ] Number properties have explicit `format` [#171]
- - [ ] Date-time uses ISO 8601 `format: date-time` [#169]
- - [ ] Enums are UPPER_SNAKE_CASE [#240]
- - [ ] Money uses common object [#173]
+ Standard-independent practice — true whatever the active standard says. The *specific* rules (pagination, error format, URL grammar, versioning) belong to the active standard; these are about the craft of contract-first design.
- ### Responses & Errors
+ **Rationalizations to reject:**
- - [ ] Every operation specifies success + error responses [#151]
- - [ ] Error responses use `application/problem+json` [#176]
- - [ ] No stack traces in error examples [#177]
- - [ ] Only official HTTP status codes used [#243]
+ | Rationalization | Reality |
+ | --- | --- |
+ | "We'll document the API later." | The contract *is* the documentation. Author it first (API-first). |
+ | "Internal APIs don't need a contract." | Internal consumers are still consumers; a contract prevents coupling and enables parallel work. |
+ | "Nobody depends on that undocumented behavior." | Hyrum's Law: every observable behavior becomes a de-facto contract. Treat it as a commitment. |
+ | "We'll handle compatibility when we need to." | Compatibility is a day-one design concern; design for extension up front (specifics per the active standard). |
- ### Pagination
+ **Red flags** (consistency properties — the active standard decides the specific rule):
- - [ ] All list endpoints paginated [#159]
- - [ ] Pagination links provided [#161]
- - [ ] Page object uses common schema [#248]
+ - A representation's shape varies across endpoints without the active standard sanctioning it.
+ - Error shape varies across endpoints without the active standard sanctioning it.
+ - Unplanned breaking changes to existing fields (type changes, removals).
+ - Authoring before reading the active standard's rules.
- ### Compatibility
+ ## Quality Gates
- - [ ] No breaking changes to existing published fields [#106]
- - [ ] Extensible enums use `examples` keyword (not closed `enum`) [#112]
- - [ ] No URL versioning [#115]
+ Before finalizing the output, verify every item in the active standard's quality-gate checklist (named in the manifest — for Zalando, [references/standards-quality-gates-zalando.md](references/standards-quality-gates-zalando.md)). A single failure means the spec is not ready.
## Output Format
- Produce a single OpenAPI 3.1 YAML document with these top-level keys:
+ Produce a single OpenAPI 3.1 YAML document. The active standard governs the specifics; in general it has these top-level keys:
- `openapi: "3.1.0"`
- - `info` — title, description, version (`MAJOR.MINOR.PATCH`) [#116][#218], contact, `x-api-id` (UUID) [#215], `x-audience` [#219]
- - `servers` — no `/api` prefix [#135]
- - `security` — global OAuth2 [#104]
- - `paths` — kebab-case [#129], plural [#134], verb-free [#141]; every operation has responses + security
- - `components/schemas` — domain schemas (snake_case [#118], explicit formats [#171]), Money [#173], Address [#249], Problem [#176], page objects [#248]
- - `components/parameters` — reusable cursor, limit, fields, sort [#137]
- - `components/responses` — reusable error responses using Problem Detail [#176]
- - `components/securitySchemes` — OAuth2 with scopes named `<api>.<resource>.<access>` [#225]
+ - `info` — title, description, version, contact, and any standard-required identifiers
+ - `servers`
+ - `security` — global auth as the standard requires
+ - `paths` — every operation has responses + security, named per the standard
+ - `components/schemas` — domain schemas plus the standard's reusable components (e.g. Money, Problem, page objects)
+ - `components/parameters` — reusable query parameters
+ - `components/responses` — reusable error responses in the standard's error format
+ - `components/securitySchemes` — auth schemes with scope naming per the standard
- See `references/golden-example.yaml` for a complete validated example.
+ For the bundled Zalando standard, see `references/golden-example.yaml` for a complete validated example.
## Reference Files
- Load selectively based on what your API needs:
+ The active standard's manifest names its rule files; load the one for the phase you're in. For the bundled Zalando standard:
| Your API has... | Load this reference |
| ---------------------------- | -------------------------------------------- |
| Multiple endpoints | naming-conventions.md |
| Non-trivial CRUD | http-methods-and-status-codes.md |
| Money, dates, or enums | data-formats-and-common-objects.md |
| List endpoints | pagination-and-filtering.md |
| Published consumers | compatibility-and-versioning.md |
| Caching or embedding needs | hypermedia-and-performance.md |
| Async events or webhooks | events.md |
Full reference index:
| Reference | Covers |
| ------------------------------------------------------------------------------------ | --------------------------------------------------------- |
+ | [standards-manifest-zalando.yaml](references/standards-manifest-zalando.yaml) | The active standard (default): attribution, rule-file map, quality gates, components |
+ | [standards-authoring.md](references/standards-authoring.md) | How to plug in your organisation's own standard (base + delta) |
+ | [standards-quality-gates-zalando.md](references/standards-quality-gates-zalando.md) | The Zalando quality-gate checklist |
| [naming-conventions.md](references/naming-conventions.md) | URL paths, property names, enums, field suffixes |
| [http-methods-and-status-codes.md](references/http-methods-and-status-codes.md) | Method semantics, status code selection, idempotency |
| [data-formats-and-common-objects.md](references/data-formats-and-common-objects.md) | Standard formats, Money, Address, Problem schemas |
| [pagination-and-filtering.md](references/pagination-and-filtering.md) | Cursor vs offset, page object, conventional params |
| [compatibility-and-versioning.md](references/compatibility-and-versioning.md) | Breaking changes, extension rules, media type versioning |
| [hypermedia-and-performance.md](references/hypermedia-and-performance.md) | REST maturity, caching, compression, partial responses |
- | [events.md](references/events.md) | All 20 event rules (#194-#247), event categories, schemas |
+ | [events.md](references/events.md) | Event rules, event categories, schemas |
---
- _Based on the [Zalando RESTful API Guidelines](https://opensource.zalando.com/restful-api-guidelines/) by Zalando SE, licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/). This is a derivative work reformatted for agent consumption._
+ _The bundled Zalando standard is a derivative work; its attribution and licence (CC-BY-4.0) live in `references/standards-manifest-zalando.yaml`._