{
  "version": "api-versions-2026.1",
  "documentationUrl": "https://apis.allanninal.dev/grapes/versioning.html",
  "current": "v1",
  "note": "The contract version in the URL path changes ONLY on a breaking change. Dataset versions move independently and are never breaking on their own. The full algorithm is in VERSIONING.md; this file is the machine-readable form of it, served at /grapes/api/v1/versions.json and enforced by scripts/check-contract.mjs.",
  "policy": {
    "breakingChangeRequires": "a new path version (/v2). The previous version keeps serving.",
    "minimumSupportWindowMonths": 12,
    "minimumDeprecationNoticeMonths": 6,
    "deprecationSignals": [
      "Deprecation header (RFC 9745) carrying the date the version was deprecated",
      "Sunset header (RFC 8594) carrying the date it stops serving",
      "Link header with rel=\"deprecation\" pointing at the migration notes",
      "a deprecation block in every JSON response body"
    ],
    "breaking": [
      "removing or renaming a response field",
      "changing the type or units of a response field",
      "removing an endpoint, or changing its path",
      "adding a required request parameter",
      "tightening validation so a previously accepted request now fails",
      "changing a default value, page size or sort order",
      "changing the meaning of an existing field without renaming it",
      "changing the shape of a record inside a published dataset"
    ],
    "additive": [
      "adding a new endpoint",
      "adding a new response field",
      "adding a new OPTIONAL request parameter",
      "adding a new enum value to a field documented as open",
      "widening validation so a previously rejected request now succeeds",
      "correcting data values, or refreshing a dataset to a newer upstream edition",
      "a Wikidata edit changing a value — the corpus is upstream data, not contract"
    ]
  },
  "versions": [
    {
      "version": "v1",
      "status": "current",
      "releasedOn": "2026-09-21",
      "deprecatedOn": null,
      "sunsetOn": null,
      "basePath": "/grapes/v1",
      "changelog": [
        {
          "release": "1.0.0",
          "date": "2026-09-21",
          "kind": "initial",
          "summary": "Reference tier: global grape varieties from Wikidata, the US 27 CFR part 4 labelling thresholds, a labelled co-occurrence graph, and a published quality register.",
          "changes": [
            "GET /v1/varieties, /v1/varieties/{id} — 2,782 varieties; an ambiguous name is 409 with candidates, never an arbitrary pick",
            "GET /v1/varieties/{id}/parents — the parentage graph, with unresolved parents kept rather than dropped",
            "GET /v1/relationships — Wikidata P186 co-occurrence claims, every one carrying its caution",
            "GET /v1/composition-rules — 27 CFR 4.23/4.25/4.27 thresholds with citations",
            "GET /v1/quality — known-bad upstream claims, colour conflicts, coverage gaps",
            "GET /v1/sources — every upstream, and everything evaluated and rejected with reasons",
            "GET /v1/changes, /v1/history/coverage — the retained corpus history",
            "GET /v1/plans, /v1/usage, /v1/version"
          ]
        }
      ]
    }
  ],
  "datasetVersioning": {
    "scheme": "<source>-<year>.<edition>",
    "example": "wikidata-varieties-2026.1",
    "rule": "A dataset version increments when the upstream data or the build that shapes it changes. Every response carries datasetVersions so a caller can pin, cache and reproduce. Refreshing a dataset is ADDITIVE: values may change, record shape may not. A change to the SHAPE of a dataset record is a breaking API change and takes a new path version.",
    "reproducibility": "Any response can be reproduced from its datasetVersions plus the build in this repo at the matching tag.",
    "upstreamChurn": "Wikidata is edited continuously, so dataset values move on every refresh. That is data moving, not contract breaking: the shape is stable and every response carries datasetVersions so a caller can pin and compare."
  }
}
