{
  "openapi": "3.1.0",
  "info": {
    "title": "EOL Watch data",
    "version": "0.1.0",
    "description": "EOL Watch tracks cloud service retirements, end of support dates and infrastructure as code breaking changes for Azure, AWS, GCP, and OCI, and every date in it comes from the source linked with it. A value the source does not state is null in the data and reads \"Not stated by vendor\" or \"Not stated in the source\" in text, and an item without a date reads \"Date not announced\": never estimate such a value. An answer that counts days says for which UTC day it counted (as_of), and a date whose precision is month, quarter or year is a period, not a day.\n\nEvery address under paths in this document is public and read only. It answers GET and HEAD and needs no key. The same data is served to MCP clients at https://eolwatch.dev/mcp (Streamable HTTP, POST, no key)."
  },
  "servers": [
    {
      "url": "https://eolwatch.dev"
    }
  ],
  "externalDocs": {
    "description": "The index for agents",
    "url": "https://eolwatch.dev/llms.txt"
  },
  "paths": {
    "/data/items.json": {
      "get": {
        "operationId": "items",
        "summary": "Items",
        "description": "What the items address answers. With at least one of its query parameters: one page of the matching items. Without any of them: the export of every published item. A parameter it does not know is ignored, with three exceptions: state, service_slug and slug are fields of a row, not parameters, and are answered with an error that says what to use.",
        "parameters": [
          {
            "name": "cloud",
            "in": "query",
            "required": false,
            "description": "Cloud of the item. Repeat the parameter or separate the values with commas to ask for several.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "azure",
                  "aws",
                  "gcp",
                  "oci",
                  "multi"
                ]
              }
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Kind of change. Repeat the parameter or separate the values with commas to ask for several. The hyphen forms of the site links (end-of-support, breaking-change) are accepted too.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "retirement",
                  "end_of_support",
                  "breaking_change"
                ]
              }
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Category group, as in the address of a category page.",
            "schema": {
              "type": "string",
              "enum": [
                "services",
                "features",
                "kubernetes",
                "runtimes",
                "databases",
                "compute-skus",
                "os-images",
                "apis-sdks",
                "iac",
                "other"
              ]
            }
          },
          {
            "name": "service",
            "in": "query",
            "required": false,
            "description": "Service slug of at most 80 characters, as in the service_slug field. Two clouds can use the same slug, so send cloud with it.",
            "schema": {
              "type": "string",
              "maxLength": 80,
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search text of at most 100 characters. Every word must occur in the title, the summary, the service, the slug or an affected version.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Earliest effective_date to include (YYYY-MM-DD). An item without a date never matches. A month, quarter or year is compared by its first day; use within_days for what is due or what ended.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Latest effective_date to include (YYYY-MM-DD). An item without a date never matches. A month, quarter or year is compared by its first day; use within_days for what is due or what ended.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "format": "date"
            }
          },
          {
            "name": "within_days",
            "in": "query",
            "required": false,
            "description": "Only items at most this many days from the as_of day (1 to 3650). With status upcoming: items due in the next N days, including an item whose month, quarter or year has started and is not over. With status ended or in_effect: items that ended or took effect in the last N days. With status all: all of these. Cannot be combined with from or to.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 3650
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "upcoming (the default): items whose effective period is not over, including items without a date. ended: retirements and end of support dates whose whole period is over. in_effect: breaking changes whose date has passed (a breaking change takes effect, it does not end, so it is never in ended). all: every item.",
            "schema": {
              "type": "string",
              "enum": [
                "upcoming",
                "ended",
                "in_effect",
                "all"
              ]
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "date (the default): by effective_date, items without a date last; a list of ended items or of changes in effect (status=ended, status=in_effect) is ordered by the last day of each effective period. added: newest first by created_at. service: by service name.",
            "schema": {
              "type": "string",
              "enum": [
                "date",
                "added",
                "service"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "asc (the default) or desc. The added order ignores it.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Most items in one answer: 1 to 200, 50 by default. With detail=full: 1 to 50, 20 by default.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of matching items to skip. Send the next_offset of an answer to get the next page.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000
            }
          },
          {
            "name": "detail",
            "in": "query",
            "required": false,
            "description": "compact (the default): one short row per item. full: the whole record of each item.",
            "schema": {
              "type": "string",
              "enum": [
                "compact",
                "full"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Items",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/items"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/invalid_parameter"
          }
        }
      }
    },
    "/data/{name}.schema.json": {
      "get": {
        "operationId": "schema",
        "summary": "The JSON Schema of one kind of answer",
        "responses": {
          "200": {
            "description": "The JSON Schema of one kind of answer",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "item",
                "items",
                "services",
                "providers",
                "provider",
                "changes",
                "error"
              ]
            }
          }
        ]
      }
    },
    "/data/services.json": {
      "get": {
        "operationId": "services",
        "summary": "Services",
        "description": "Every service that has a published item, with its counts and the date of its next item.",
        "responses": {
          "200": {
            "description": "Services",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/services"
                }
              }
            }
          }
        }
      }
    },
    "/data/providers.json": {
      "get": {
        "operationId": "providers",
        "summary": "Providers, tools and modules",
        "description": "Every infrastructure as code provider, tool and module whose releases are read for breaking changes, with its newest tracked release.",
        "responses": {
          "200": {
            "description": "Providers, tools and modules",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/providers"
                }
              }
            }
          }
        }
      }
    },
    "/data/changes.json": {
      "get": {
        "operationId": "changes",
        "summary": "Changes",
        "description": "One page of the changelog: items added, dates changed, items updated and items withdrawn, newest first.",
        "parameters": [
          {
            "name": "cloud",
            "in": "query",
            "required": false,
            "description": "Only changes to items of this cloud.",
            "schema": {
              "type": "string",
              "enum": [
                "azure",
                "aws",
                "gcp",
                "oci",
                "multi"
              ]
            }
          },
          {
            "name": "change",
            "in": "query",
            "required": false,
            "description": "Only this kind of change: added, date_changed, updated or withdrawn.",
            "schema": {
              "type": "string",
              "enum": [
                "added",
                "date_changed",
                "updated",
                "withdrawn"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page of the changelog, from 1. One page holds 50 changes, and a page past the end is the last page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Changes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/changes"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/invalid_parameter"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "openapi",
        "summary": "This OpenAPI description",
        "responses": {
          "200": {
            "description": "This OpenAPI description",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/index.md": {
      "get": {
        "operationId": "home_md",
        "summary": "The home page as Markdown",
        "description": "What is due in the next 90 days, soonest first. Both forms also hold the four counts of the countdown strip and the lists the page shows under its main list (Recently added, Recently ended, IaC this week): in JSON they are the fields windows and sections. The query string of a home page link is accepted, so the list of a filtered view can be read here. A value that is not allowed is ignored. A service slug the site does not have is kept as a filter and matches nothing. A view that differs from the home page (a filter, another window, another order, a later page) has no windows, and its sections hold those lists only when it has no filter and the default window. To ask for a list with filters of your own, use /data/items.json.",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "30",
                "90",
                "180",
                "all",
                "ended"
              ]
            }
          },
          {
            "name": "cloud",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "azure",
                  "aws",
                  "gcp",
                  "oci",
                  "multi"
                ]
              }
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "retirement",
                  "end-of-support",
                  "breaking-change",
                  "end_of_support",
                  "breaking_change"
                ]
              }
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "services",
                "features",
                "kubernetes",
                "runtimes",
                "databases",
                "compute-skus",
                "os-images",
                "apis-sdks",
                "iac",
                "other"
              ]
            }
          },
          {
            "name": "service",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 80,
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "date",
                "added",
                "service"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "table",
                "timeline"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "zoom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                3,
                6,
                12,
                24
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The home page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/index.json": {
      "get": {
        "operationId": "home_json",
        "summary": "The home page as JSON",
        "description": "What is due in the next 90 days, soonest first. Both forms also hold the four counts of the countdown strip and the lists the page shows under its main list (Recently added, Recently ended, IaC this week): in JSON they are the fields windows and sections. The query string of a home page link is accepted, so the list of a filtered view can be read here. A value that is not allowed is ignored. A service slug the site does not have is kept as a filter and matches nothing. A view that differs from the home page (a filter, another window, another order, a later page) has no windows, and its sections hold those lists only when it has no filter and the default window. To ask for a list with filters of your own, use /data/items.json.",
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "30",
                "90",
                "180",
                "all",
                "ended"
              ]
            }
          },
          {
            "name": "cloud",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "azure",
                  "aws",
                  "gcp",
                  "oci",
                  "multi"
                ]
              }
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "retirement",
                  "end-of-support",
                  "breaking-change",
                  "end_of_support",
                  "breaking_change"
                ]
              }
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "services",
                "features",
                "kubernetes",
                "runtimes",
                "databases",
                "compute-skus",
                "os-images",
                "apis-sdks",
                "iac",
                "other"
              ]
            }
          },
          {
            "name": "service",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 80,
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "date",
                "added",
                "service"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "table",
                "timeline"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "zoom",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "enum": [
                3,
                6,
                12,
                24
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The home page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/item_list"
                }
              }
            }
          }
        }
      }
    },
    "/items/{slug}.md": {
      "get": {
        "operationId": "item_md",
        "summary": "An item page as Markdown",
        "description": "One published lifecycle item: a retirement, an end of support date or a breaking change, with the source its date was read from.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Stable identifier of the item. Never changes once published.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "An item page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found_markdown"
          },
          "410": {
            "$ref": "#/components/responses/gone_markdown"
          }
        }
      }
    },
    "/items/{slug}.json": {
      "get": {
        "operationId": "item_json",
        "summary": "An item page as JSON",
        "description": "One published lifecycle item: a retirement, an end of support date or a breaking change, with the source its date was read from.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Stable identifier of the item. Never changes once published.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "An item page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/item"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found"
          },
          "410": {
            "$ref": "#/components/responses/gone"
          }
        }
      }
    },
    "/services/{cloud}/{service}.md": {
      "get": {
        "operationId": "service_md",
        "summary": "A service page as Markdown",
        "description": "Every published item of one service: upcoming, ended and in effect. The JSON form holds whole records and is never cut, so the versions and the replacements of the version table of the page are in it. It can hold more records than one request of the item query may ask for: the query it states then has a limit the items address refuses. The lists of the page (upcoming, ended, in effect) are the field sections in JSON: compact rows in the order of the page, each with its state and its days, and the data address that answers the same rows, or null when no address answers them in that order.",
        "parameters": [
          {
            "name": "cloud",
            "in": "path",
            "required": true,
            "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi.",
            "schema": {
              "type": "string",
              "enum": [
                "azure",
                "aws",
                "gcp",
                "oci",
                "multi"
              ]
            }
          },
          {
            "name": "service",
            "in": "path",
            "required": true,
            "description": "URL-safe identifier of the service.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A service page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found_markdown"
          }
        }
      }
    },
    "/services/{cloud}/{service}.json": {
      "get": {
        "operationId": "service_json",
        "summary": "A service page as JSON",
        "description": "Every published item of one service: upcoming, ended and in effect. The JSON form holds whole records and is never cut, so the versions and the replacements of the version table of the page are in it. It can hold more records than one request of the item query may ask for: the query it states then has a limit the items address refuses. The lists of the page (upcoming, ended, in effect) are the field sections in JSON: compact rows in the order of the page, each with its state and its days, and the data address that answers the same rows, or null when no address answers them in that order.",
        "parameters": [
          {
            "name": "cloud",
            "in": "path",
            "required": true,
            "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi.",
            "schema": {
              "type": "string",
              "enum": [
                "azure",
                "aws",
                "gcp",
                "oci",
                "multi"
              ]
            }
          },
          {
            "name": "service",
            "in": "path",
            "required": true,
            "description": "URL-safe identifier of the service.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A service page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/item_list"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found"
          }
        }
      }
    },
    "/providers/{key}.md": {
      "get": {
        "operationId": "provider_md",
        "summary": "A provider page as Markdown",
        "description": "What a provider page shows: the tracked range, the summary sentence, the notices and the releases that list breaking changes.",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "Key of the entry: the provider key (for example azurerm) or the name of the module. It is the last part of its page address.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "enum": [
                "azurerm",
                "azapi",
                "aws",
                "oci",
                "bicep",
                "avm-res-network-virtualnetwork",
                "avm-res-storage-storageaccount",
                "avm-res-network-networksecuritygroup",
                "avm-res-compute-virtualmachine",
                "avm-res-resources-resourcegroup",
                "avm-res-managedidentity-userassignedidentity",
                "avm-res-network-privatednszone",
                "avm-res-operationalinsights-workspace",
                "avm-res-network-routetable",
                "avm-res-network-natgateway",
                "avm-res-network-publicipaddress",
                "avm-res-cognitiveservices-account",
                "avm-res-network-firewallpolicy",
                "avm-res-containerregistry-registry",
                "avm-res-containerservice-managedcluster",
                "avm-res-network-privateendpoint",
                "avm-res-web-site",
                "avm-res-network-loadbalancer",
                "avm-res-dbforpostgresql-flexibleserver",
                "avm-res-network-bastionhost"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "The version in use, or a version constraint, of at most 64 characters. Only releases newer than that version are in the answer. For a constraint, that version is the lowest one the constraint allows. Leave it out for every tracked release whose release notes were read and list a breaking change.",
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A provider page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found_markdown"
          }
        }
      }
    },
    "/providers/{key}.json": {
      "get": {
        "operationId": "provider_json",
        "summary": "A provider page as JSON",
        "description": "What a provider page shows: the tracked range, the summary sentence, the notices and the releases that list breaking changes.",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "Key of the entry: the provider key (for example azurerm) or the name of the module. It is the last part of its page address.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "enum": [
                "azurerm",
                "azapi",
                "aws",
                "oci",
                "bicep",
                "avm-res-network-virtualnetwork",
                "avm-res-storage-storageaccount",
                "avm-res-network-networksecuritygroup",
                "avm-res-compute-virtualmachine",
                "avm-res-resources-resourcegroup",
                "avm-res-managedidentity-userassignedidentity",
                "avm-res-network-privatednszone",
                "avm-res-operationalinsights-workspace",
                "avm-res-network-routetable",
                "avm-res-network-natgateway",
                "avm-res-network-publicipaddress",
                "avm-res-cognitiveservices-account",
                "avm-res-network-firewallpolicy",
                "avm-res-containerregistry-registry",
                "avm-res-containerservice-managedcluster",
                "avm-res-network-privateendpoint",
                "avm-res-web-site",
                "avm-res-network-loadbalancer",
                "avm-res-dbforpostgresql-flexibleserver",
                "avm-res-network-bastionhost"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "The version in use, or a version constraint, of at most 64 characters. Only releases newer than that version are in the answer. For a constraint, that version is the lowest one the constraint allows. Leave it out for every tracked release whose release notes were read and list a breaking change.",
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A provider page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/provider"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found"
          }
        }
      }
    },
    "/cloud/{cloud}.md": {
      "get": {
        "operationId": "cloud_md",
        "summary": "A cloud page as Markdown",
        "description": "The upcoming items of one cloud, soonest first. Both forms also hold the breaking changes of the cloud that took effect in the last 90 days, when it has any: in JSON they are the field sections.",
        "parameters": [
          {
            "name": "cloud",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "azure",
                "aws",
                "gcp",
                "oci"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A cloud page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found_markdown"
          }
        }
      }
    },
    "/cloud/{cloud}.json": {
      "get": {
        "operationId": "cloud_json",
        "summary": "A cloud page as JSON",
        "description": "The upcoming items of one cloud, soonest first. Both forms also hold the breaking changes of the cloud that took effect in the last 90 days, when it has any: in JSON they are the field sections.",
        "parameters": [
          {
            "name": "cloud",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "azure",
                "aws",
                "gcp",
                "oci"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A cloud page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/item_list"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found"
          }
        }
      }
    },
    "/categories/{category}.md": {
      "get": {
        "operationId": "category_md",
        "summary": "A category page as Markdown",
        "description": "The items of one category group, as its page lists them. Both forms also hold the breaking changes of the category that took effect in the last 90 days, when it has any: in JSON they are the field sections.",
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "description": "Category group, as in the address of a category page.",
            "schema": {
              "type": "string",
              "enum": [
                "services",
                "features",
                "kubernetes",
                "runtimes",
                "databases",
                "compute-skus",
                "os-images",
                "apis-sdks",
                "iac",
                "other"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A category page as Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found_markdown"
          }
        }
      }
    },
    "/categories/{category}.json": {
      "get": {
        "operationId": "category_json",
        "summary": "A category page as JSON",
        "description": "The items of one category group, as its page lists them. Both forms also hold the breaking changes of the category that took effect in the last 90 days, when it has any: in JSON they are the field sections.",
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "description": "Category group, as in the address of a category page.",
            "schema": {
              "type": "string",
              "enum": [
                "services",
                "features",
                "kubernetes",
                "runtimes",
                "databases",
                "compute-skus",
                "os-images",
                "apis-sdks",
                "iac",
                "other"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A category page as JSON",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/item_list"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/not_found"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "item": {
        "title": "Item",
        "description": "One published lifecycle item: a retirement, an end of support date or a breaking change, with the source its date was read from.",
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "minLength": 1,
            "description": "Stable identifier of the item. Never changes once published."
          },
          "title": {
            "type": "string",
            "description": "Short headline of the lifecycle change."
          },
          "summary": {
            "type": "string",
            "description": "One or two plain sentences describing the change."
          },
          "cloud": {
            "type": "string",
            "enum": [
              "azure",
              "aws",
              "gcp",
              "oci",
              "multi"
            ],
            "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi."
          },
          "service": {
            "type": "string",
            "description": "Display name of the affected service."
          },
          "service_slug": {
            "type": "string",
            "minLength": 1,
            "description": "URL-safe identifier of the service."
          },
          "category": {
            "type": "string",
            "enum": [
              "service",
              "feature",
              "kubernetes",
              "runtime",
              "database",
              "compute_sku",
              "os_image",
              "api_sdk",
              "iac_provider",
              "iac_module",
              "iac_language",
              "other"
            ],
            "description": "Kind of thing affected, for example service, runtime, kubernetes or database."
          },
          "type": {
            "type": "string",
            "enum": [
              "retirement",
              "end_of_support",
              "breaking_change"
            ],
            "description": "Kind of change: retirement, end_of_support or breaking_change."
          },
          "announced_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date the vendor announced the change (YYYY-MM-DD), or null when not stated."
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
          },
          "effective_precision": {
            "type": "string",
            "enum": [
              "day",
              "month",
              "quarter",
              "year"
            ],
            "description": "How exact effective_date is: day, month, quarter or year."
          },
          "impact": {
            "type": "string",
            "description": "What stops working and who is affected."
          },
          "migration_path": {
            "type": "string",
            "description": "Steps to take before the effective date. May contain Markdown."
          },
          "replacement": {
            "description": "Recommended replacement, or null when the vendor names none.",
            "type": [
              "string",
              "null"
            ]
          },
          "affected_versions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Versions affected. Array in JSON, joined with \"; \" in CSV."
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Page the item was verified against: an official vendor page, or the endoflife.date page for the few products where it is the only source of the date."
          },
          "extra_source_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Additional sources: official pages, or an endoflife.date page. Array in JSON, joined with \"; \" in CSV."
          },
          "vendor_ref": {
            "description": "Vendor reference for the announcement, or null.",
            "type": [
              "string",
              "null"
            ]
          },
          "last_checked_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Timestamp (ISO 8601, UTC) of the last successful recheck against the source."
          },
          "created_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Timestamp (ISO 8601, UTC) when the item was first published here."
          },
          "updated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Timestamp (ISO 8601, UTC) of the last change to the item."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Page for this item on the site."
          },
          "short_url": {
            "type": "string",
            "format": "uri",
            "description": "Short address of the item page. It redirects to url."
          },
          "markdown_url": {
            "type": "string",
            "format": "uri",
            "description": "The same item as Markdown."
          },
          "json_url": {
            "type": "string",
            "format": "uri",
            "description": "The same item as JSON."
          },
          "estate_check": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "resource_types": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The resource types the rules of the item name, in the order of the rules."
                  },
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The fields and Terraform paths the check reads, in the order of the rules."
                  },
                  "inputs": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "The kinds of file the estate check can detect the item from."
                  }
                },
                "required": [
                  "resource_types",
                  "fields",
                  "inputs"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "What the estate check reads to detect resources this item affects, as the item page lists it. Null when the item has no estate check rules. The check runs in the browser of the reader: no address of this site takes a file, a resource ID or a subscription ID."
          }
        },
        "required": [
          "slug",
          "title",
          "summary",
          "cloud",
          "service",
          "service_slug",
          "category",
          "type",
          "announced_date",
          "effective_date",
          "effective_precision",
          "impact",
          "migration_path",
          "replacement",
          "affected_versions",
          "source_url",
          "extra_source_urls",
          "vendor_ref",
          "last_checked_at",
          "created_at",
          "updated_at",
          "url",
          "short_url",
          "markdown_url",
          "json_url",
          "estate_check"
        ],
        "additionalProperties": false
      },
      "items": {
        "title": "Items",
        "description": "What the items address answers. With at least one of its query parameters: one page of the matching items. Without any of them: the export of every published item. A parameter it does not know is ignored, with three exceptions: state, service_slug and slug are fields of a row, not parameters, and are answered with an error that says what to use.",
        "anyOf": [
          {
            "$ref": "#/components/schemas/item_list"
          },
          {
            "$ref": "#/components/schemas/items_export"
          }
        ]
      },
      "services": {
        "title": "Services",
        "description": "Every service that has a published item, with its counts and the date of its next item.",
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Moment this answer was built (ISO 8601, UTC)."
          },
          "as_of": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date",
            "description": "The UTC day (YYYY-MM-DD) every value that depends on the day was counted for."
          },
          "site": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the site."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Address of the site."
              }
            },
            "required": [
              "name",
              "url"
            ],
            "additionalProperties": false,
            "description": "The site the data comes from."
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the license, or the words that say none is chosen yet."
              },
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Address of the license text, or null when there is none."
              },
              "note": {
                "type": "string",
                "description": "What that means for reuse of the data."
              }
            },
            "required": [
              "name",
              "url",
              "note"
            ],
            "additionalProperties": false,
            "description": "The license of the data."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of services in this answer."
          },
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "cloud": {
                  "type": "string",
                  "enum": [
                    "azure",
                    "aws",
                    "gcp",
                    "oci",
                    "multi"
                  ],
                  "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi."
                },
                "service": {
                  "type": "string",
                  "description": "Display name of the affected service."
                },
                "service_slug": {
                  "type": "string",
                  "minLength": 1,
                  "description": "URL-safe identifier of the service."
                },
                "count": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of published items for the service."
                },
                "upcoming": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "How many of them are upcoming on the as_of day: the effective period is not over. An item without a date counts as upcoming."
                },
                "next_effective_date": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                      "format": "date"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The effective_date of the soonest upcoming item of the service, or null when none has a date. For a month, quarter or year this is the first day of the period."
                },
                "next_effective_precision": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "day",
                        "month",
                        "quarter",
                        "year"
                      ]
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "How exact next_effective_date is: day, month, quarter or year. Null without a date."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page of the service on the site."
                },
                "markdown_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The same page as Markdown."
                },
                "json_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The items of the service as JSON."
                }
              },
              "required": [
                "cloud",
                "service",
                "service_slug",
                "count",
                "upcoming",
                "next_effective_date",
                "next_effective_precision",
                "url",
                "markdown_url",
                "json_url"
              ],
              "additionalProperties": false
            },
            "description": "The services, by cloud and then by name."
          }
        },
        "required": [
          "generated_at",
          "as_of",
          "site",
          "license",
          "count",
          "services"
        ],
        "additionalProperties": false
      },
      "providers": {
        "title": "Providers, tools and modules",
        "description": "Every infrastructure as code provider, tool and module whose releases are read for breaking changes, with its newest tracked release.",
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Moment this answer was built (ISO 8601, UTC)."
          },
          "as_of": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date",
            "description": "The UTC day (YYYY-MM-DD) every value that depends on the day was counted for."
          },
          "site": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the site."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Address of the site."
              }
            },
            "required": [
              "name",
              "url"
            ],
            "additionalProperties": false,
            "description": "The site the data comes from."
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the license, or the words that say none is chosen yet."
              },
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Address of the license text, or null when there is none."
              },
              "note": {
                "type": "string",
                "description": "What that means for reuse of the data."
              }
            },
            "required": [
              "name",
              "url",
              "note"
            ],
            "additionalProperties": false,
            "description": "The license of the data."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of entries in this answer."
          },
          "providers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Key of the entry: the provider key (for example azurerm) or the name of the module. It is the last part of its page address."
                },
                "name": {
                  "type": "string",
                  "description": "Display name of the entry."
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "provider",
                    "tool",
                    "module"
                  ],
                  "description": "What the entry is: a Terraform provider, a tool or language, or a module."
                },
                "cloud": {
                  "type": "string",
                  "enum": [
                    "azure",
                    "aws",
                    "gcp",
                    "oci",
                    "multi"
                  ],
                  "description": "Cloud the entry belongs to."
                },
                "namespace": {
                  "type": "string",
                  "description": "Where the entry is published: its address in the Terraform Registry, or its GitHub repository when it is not in the registry."
                },
                "registry_url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Page of a module in the Terraform Registry. Null for providers and tools."
                },
                "subject": {
                  "description": "What a module deploys, as the Azure Verified Modules index names it. Null for providers and tools.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "repo_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The GitHub repository whose releases are read."
                },
                "latest_version": {
                  "description": "The newest tracked stable release, without a leading v. Null when none is loaded.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "latest_date": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                      "format": "date"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Day that release was published (YYYY-MM-DD), or null when it is not known."
                },
                "latest_confirmed": {
                  "type": "boolean",
                  "description": "True when the tracked list holds every stable release from oldest_tracked_version on, so latest_version is the latest stable release. False when it is only the newest release tracked here: a newer one may exist."
                },
                "latest_notes_read": {
                  "description": "False when the newest release is known from the Terraform Registry only and has no GitHub release: its release notes were not read. Null when no release is loaded.",
                  "type": [
                    "boolean",
                    "null"
                  ]
                },
                "oldest_tracked_version": {
                  "description": "The oldest tracked stable release. Releases before it were not read. Null when none is loaded.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "breaking_releases_last_12_months": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of tracked stable releases published in the twelve months up to the as_of day whose release notes were read and list at least one breaking change."
                },
                "counted_since": {
                  "description": "Set when the tracked releases start less than twelve months before the as_of day: the oldest tracked version, where that count really starts. Null otherwise.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page of the entry on the site."
                },
                "markdown_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The same page as Markdown."
                },
                "json_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The same page as JSON."
                },
                "latest_notes_url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The page latest_version and latest_date were read from: its release notes, or its page in the Terraform Registry. Null when no release is loaded."
                },
                "tracked_releases": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of tracked stable releases."
                },
                "breaking_releases": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of tracked stable releases whose release notes were read and list at least one breaking change."
                }
              },
              "required": [
                "key",
                "name",
                "kind",
                "cloud",
                "namespace",
                "registry_url",
                "subject",
                "repo_url",
                "latest_version",
                "latest_date",
                "latest_confirmed",
                "latest_notes_read",
                "oldest_tracked_version",
                "breaking_releases_last_12_months",
                "counted_since",
                "url",
                "markdown_url",
                "json_url",
                "latest_notes_url",
                "tracked_releases",
                "breaking_releases"
              ],
              "additionalProperties": false
            },
            "description": "The providers and tools, then the modules, in the order of the site."
          }
        },
        "required": [
          "generated_at",
          "as_of",
          "site",
          "license",
          "count",
          "providers"
        ],
        "additionalProperties": false
      },
      "provider": {
        "title": "Breaking changes of one provider, tool or module",
        "description": "What a provider page shows: the tracked range, the summary sentence, the notices and the releases that list breaking changes.",
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "Key of the entry: the provider key (for example azurerm) or the name of the module. It is the last part of its page address."
          },
          "name": {
            "type": "string",
            "description": "Display name of the entry."
          },
          "kind": {
            "type": "string",
            "enum": [
              "provider",
              "tool",
              "module"
            ],
            "description": "What the entry is: a Terraform provider, a tool or language, or a module."
          },
          "cloud": {
            "type": "string",
            "enum": [
              "azure",
              "aws",
              "gcp",
              "oci",
              "multi"
            ],
            "description": "Cloud the entry belongs to."
          },
          "namespace": {
            "type": "string",
            "description": "Where the entry is published: its address in the Terraform Registry, or its GitHub repository when it is not in the registry."
          },
          "registry_url": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page of a module in the Terraform Registry. Null for providers and tools."
          },
          "subject": {
            "description": "What a module deploys, as the Azure Verified Modules index names it. Null for providers and tools.",
            "type": [
              "string",
              "null"
            ]
          },
          "repo_url": {
            "type": "string",
            "format": "uri",
            "description": "The GitHub repository whose releases are read."
          },
          "latest_version": {
            "description": "The newest tracked stable release, without a leading v. Null when none is loaded.",
            "type": [
              "string",
              "null"
            ]
          },
          "latest_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Day that release was published (YYYY-MM-DD), or null when it is not known."
          },
          "latest_confirmed": {
            "type": "boolean",
            "description": "True when the tracked list holds every stable release from oldest_tracked_version on, so latest_version is the latest stable release. False when it is only the newest release tracked here: a newer one may exist."
          },
          "latest_notes_read": {
            "description": "False when the newest release is known from the Terraform Registry only and has no GitHub release: its release notes were not read. Null when no release is loaded.",
            "type": [
              "boolean",
              "null"
            ]
          },
          "oldest_tracked_version": {
            "description": "The oldest tracked stable release. Releases before it were not read. Null when none is loaded.",
            "type": [
              "string",
              "null"
            ]
          },
          "breaking_releases_last_12_months": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of tracked stable releases published in the twelve months up to the as_of day whose release notes were read and list at least one breaking change."
          },
          "counted_since": {
            "description": "Set when the tracked releases start less than twelve months before the as_of day: the oldest tracked version, where that count really starts. Null otherwise.",
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Page of the entry on the site."
          },
          "markdown_url": {
            "type": "string",
            "format": "uri",
            "description": "The same page as Markdown."
          },
          "json_url": {
            "type": "string",
            "format": "uri",
            "description": "The same page as JSON."
          },
          "as_of": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date",
            "description": "The UTC day (YYYY-MM-DD) every value that depends on the day was counted for."
          },
          "from": {
            "description": "The version in use that the answer starts from, as plain semver. For a constraint it is the lowest version the constraint allows. Only newer releases are in the answer. Null when no version was given or when the value sent is not a version or a constraint.",
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "all",
              "invalid",
              "range",
              "clear",
              "partial"
            ],
            "description": "How the answer was chosen. all: no version was given, so every tracked release whose release notes were read and list a breaking change is in it. range: the tracked releases newer than from whose release notes were read and list a breaking change are in it. clear: from is not older than the oldest tracked release, the release notes of every tracked release newer than from were read, and none lists one. partial: among the tracked releases newer than from whose release notes were read, none lists one, but part of the range was not read: from is older than the oldest tracked release, or the release notes of a tracked release newer than from were not read. Such a range is not clear. invalid: the value sent as from is not a version or a constraint, so the answer is the same as for all. In every state, read the notices before you call a range clear."
          },
          "summary": {
            "type": "string",
            "description": "The summary sentence of the page for this answer."
          },
          "notices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The sentences that go with the summary: a range that reaches below the oldest tracked release and versions whose release notes were not read, both word for word from the page, and a from value that could not be read. Empty when the summary stands on its own."
          },
          "unread_versions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The versions in the answered range whose release notes were not read, newest first. Nothing is known about breaking changes in them, and they are not in releases."
          },
          "releases": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "version": {
                  "type": "string",
                  "description": "Version of the release, without a leading v."
                },
                "date": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                      "format": "date"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Day the release was published (YYYY-MM-DD), or null when it is not known."
                },
                "is_major": {
                  "type": "boolean",
                  "description": "True when the release opens a new major version."
                },
                "notes_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The release notes of the version."
                },
                "notes_read": {
                  "type": "boolean",
                  "description": "True when the release notes were read. Every release in releases has notes that were read: a version whose release notes were not read is in unread_versions and not in releases."
                },
                "upgrade_guide_url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The upgrade guide for the release, or null when there is none."
                },
                "breaking": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "resource": {
                        "description": "The resource, data source or setting the change is about, or null when the release notes name none.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "text": {
                        "type": "string",
                        "description": "The change, as the release notes list it."
                      },
                      "link": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uri"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "Where the change is described in more detail, or null when no link is given."
                      }
                    },
                    "required": [
                      "resource",
                      "text",
                      "link"
                    ],
                    "additionalProperties": false
                  },
                  "description": "The breaking changes the release notes list, in their order."
                }
              },
              "required": [
                "version",
                "date",
                "is_major",
                "notes_url",
                "notes_read",
                "upgrade_guide_url",
                "breaking"
              ],
              "additionalProperties": false
            },
            "description": "The releases in the answered range whose release notes were read and list a breaking change, newest first."
          },
          "short_url": {
            "type": "string",
            "format": "uri",
            "description": "Short address of the page for this answer. It redirects to url."
          }
        },
        "required": [
          "key",
          "name",
          "kind",
          "cloud",
          "namespace",
          "registry_url",
          "subject",
          "repo_url",
          "latest_version",
          "latest_date",
          "latest_confirmed",
          "latest_notes_read",
          "oldest_tracked_version",
          "breaking_releases_last_12_months",
          "counted_since",
          "url",
          "markdown_url",
          "json_url",
          "as_of",
          "from",
          "state",
          "summary",
          "notices",
          "unread_versions",
          "releases",
          "short_url"
        ],
        "additionalProperties": false
      },
      "changes": {
        "title": "Changes",
        "description": "One page of the changelog: items added, dates changed, items updated and items withdrawn, newest first.",
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Moment this answer was built (ISO 8601, UTC)."
          },
          "site": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the site."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Address of the site."
              }
            },
            "required": [
              "name",
              "url"
            ],
            "additionalProperties": false,
            "description": "The site the data comes from."
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the license, or the words that say none is chosen yet."
              },
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Address of the license text, or null when there is none."
              },
              "note": {
                "type": "string",
                "description": "What that means for reuse of the data."
              }
            },
            "required": [
              "name",
              "url",
              "note"
            ],
            "additionalProperties": false,
            "description": "The license of the data."
          },
          "query": {
            "type": "object",
            "properties": {
              "cloud": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "azure",
                      "aws",
                      "gcp",
                      "oci",
                      "multi"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Cloud asked for, or null for every cloud."
              },
              "change": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "added",
                      "date_changed",
                      "updated",
                      "withdrawn"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Kind of change asked for (added, date_changed, updated or withdrawn), or null."
              },
              "page": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Page asked for, from 1."
              }
            },
            "required": [
              "cloud",
              "change",
              "page"
            ],
            "additionalProperties": false,
            "description": "The query as it was understood."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of changes that match the query."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of changes in this answer."
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "The page this answer holds. A page past the end is the last page."
          },
          "pages": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Number of pages."
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "minimum": -9007199254740991,
                  "maximum": 9007199254740991,
                  "description": "Identifier of the change."
                },
                "change": {
                  "type": "string",
                  "enum": [
                    "added",
                    "date_changed",
                    "updated",
                    "withdrawn"
                  ],
                  "description": "Kind of change: added (the item was published), date_changed (its effective date changed), updated (another field changed) or withdrawn (the item is no longer listed)."
                },
                "changed_at": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
                  "format": "date-time",
                  "description": "Moment of the change (ISO 8601, UTC)."
                },
                "slug": {
                  "type": "string",
                  "description": "Slug of the item the change is about."
                },
                "title": {
                  "type": "string",
                  "description": "Title of that item."
                },
                "cloud": {
                  "type": "string",
                  "enum": [
                    "azure",
                    "aws",
                    "gcp",
                    "oci",
                    "multi"
                  ],
                  "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi."
                },
                "text": {
                  "type": "string",
                  "description": "The change in one sentence, as the changelog page words it."
                },
                "before": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "effective_date": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                              "format": "date"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
                        },
                        "effective_precision": {
                          "type": "string",
                          "enum": [
                            "day",
                            "month",
                            "quarter",
                            "year"
                          ],
                          "description": "How exact effective_date is: day, month, quarter or year."
                        }
                      },
                      "required": [
                        "effective_date",
                        "effective_precision"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "For a date change: the effective date before it. Null for every other change."
                },
                "after": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "effective_date": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                              "format": "date"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
                        },
                        "effective_precision": {
                          "type": "string",
                          "enum": [
                            "day",
                            "month",
                            "quarter",
                            "year"
                          ],
                          "description": "How exact effective_date is: day, month, quarter or year."
                        }
                      },
                      "required": [
                        "effective_date",
                        "effective_precision"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "For a date change: the effective date after it. Null for every other change."
                },
                "source_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page the item was verified against: an official vendor page, or the endoflife.date page for the few products where it is the only source of the date."
                },
                "url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Page of the item, or null when the item has no page: it was withdrawn."
                },
                "markdown_url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The item as Markdown, or null without a page."
                },
                "json_url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The item as JSON, or null without a page."
                }
              },
              "required": [
                "id",
                "change",
                "changed_at",
                "slug",
                "title",
                "cloud",
                "text",
                "before",
                "after",
                "source_url",
                "url",
                "markdown_url",
                "json_url"
              ],
              "additionalProperties": false
            },
            "description": "The changes of this page, newest first."
          }
        },
        "required": [
          "generated_at",
          "site",
          "license",
          "query",
          "total",
          "count",
          "page",
          "pages",
          "items"
        ],
        "additionalProperties": false
      },
      "error": {
        "title": "Error",
        "description": "The answer of a request that cannot be served.",
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_parameter",
                  "not_found",
                  "method_not_allowed",
                  "not_acceptable",
                  "gone"
                ],
                "description": "Kind of error."
              },
              "message": {
                "type": "string",
                "description": "What is wrong, in plain words."
              },
              "parameter": {
                "description": "The query parameter the error is about, or the name that was sent as one.",
                "type": "string"
              },
              "allowed": {
                "description": "What that parameter accepts: its values, or its range in words.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "item_row": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "minLength": 1,
            "description": "Stable identifier of the item. Never changes once published."
          },
          "title": {
            "type": "string",
            "description": "Short headline of the lifecycle change."
          },
          "cloud": {
            "type": "string",
            "enum": [
              "azure",
              "aws",
              "gcp",
              "oci",
              "multi"
            ],
            "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi."
          },
          "service": {
            "type": "string",
            "description": "Display name of the affected service."
          },
          "service_slug": {
            "type": "string",
            "minLength": 1,
            "description": "URL-safe identifier of the service."
          },
          "category": {
            "type": "string",
            "enum": [
              "service",
              "feature",
              "kubernetes",
              "runtime",
              "database",
              "compute_sku",
              "os_image",
              "api_sdk",
              "iac_provider",
              "iac_module",
              "iac_language",
              "other"
            ],
            "description": "Kind of thing affected, for example service, runtime, kubernetes or database."
          },
          "type": {
            "type": "string",
            "enum": [
              "retirement",
              "end_of_support",
              "breaking_change"
            ],
            "description": "Kind of change: retirement, end_of_support or breaking_change."
          },
          "announced_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date the vendor announced the change (YYYY-MM-DD), or null when not stated."
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
          },
          "effective_precision": {
            "type": "string",
            "enum": [
              "day",
              "month",
              "quarter",
              "year"
            ],
            "description": "How exact effective_date is: day, month, quarter or year."
          },
          "state": {
            "type": "string",
            "enum": [
              "upcoming",
              "ended",
              "in_effect",
              "no_date"
            ],
            "description": "Where the item stands on the as_of day: upcoming (its effective period is not over), ended (a retirement or an end of support whose whole period is over), in_effect (a breaking change whose date has passed: it took effect, it does not end) or no_date (no date is announced)."
          },
          "days": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "Calendar days from the as_of day to the first day of the effective period. Zero or negative once that day has come. Null when there is no date. A month, quarter or year is over only after its last day, so read state to know whether an item has ended or is in effect. For an item dated by month, quarter or year that has ended, this is not the number of days since it ended: the pages count those from the last day of the period."
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "Page the item was verified against: an official vendor page, or the endoflife.date page for the few products where it is the only source of the date."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Page for this item on the site."
          },
          "markdown_url": {
            "type": "string",
            "format": "uri",
            "description": "The same item as Markdown."
          },
          "json_url": {
            "type": "string",
            "format": "uri",
            "description": "The same item as JSON."
          }
        },
        "required": [
          "slug",
          "title",
          "cloud",
          "service",
          "service_slug",
          "category",
          "type",
          "announced_date",
          "effective_date",
          "effective_precision",
          "state",
          "days",
          "source_url",
          "url",
          "markdown_url",
          "json_url"
        ],
        "additionalProperties": false
      },
      "item_list": {
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Moment this answer was built (ISO 8601, UTC)."
          },
          "as_of": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "format": "date",
            "description": "The UTC day (YYYY-MM-DD) every value that depends on the day was counted for."
          },
          "site": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the site."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Address of the site."
              }
            },
            "required": [
              "name",
              "url"
            ],
            "additionalProperties": false,
            "description": "The site the data comes from."
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the license, or the words that say none is chosen yet."
              },
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Address of the license text, or null when there is none."
              },
              "note": {
                "type": "string",
                "description": "What that means for reuse of the data."
              }
            },
            "required": [
              "name",
              "url",
              "note"
            ],
            "additionalProperties": false,
            "description": "The license of the data."
          },
          "query": {
            "type": "object",
            "properties": {
              "cloud": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "azure",
                    "aws",
                    "gcp",
                    "oci",
                    "multi"
                  ]
                },
                "description": "Clouds asked for. Empty: every cloud."
              },
              "type": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "retirement",
                    "end_of_support",
                    "breaking_change"
                  ]
                },
                "description": "Kinds of change asked for. Empty: every kind."
              },
              "category": {
                "anyOf": [
                  {
                    "type": "string",
                    "enum": [
                      "services",
                      "features",
                      "kubernetes",
                      "runtimes",
                      "databases",
                      "compute-skus",
                      "os-images",
                      "apis-sdks",
                      "iac",
                      "other"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Category group asked for, or null."
              },
              "service": {
                "description": "Service slug asked for, or null.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "q": {
                "description": "Search text as it was used, or null.",
                "type": [
                  "string",
                  "null"
                ]
              },
              "from": {
                "anyOf": [
                  {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "format": "date"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Earliest effective_date asked for, or null."
              },
              "to": {
                "anyOf": [
                  {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "format": "date"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Latest effective_date asked for, or null."
              },
              "within_days": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Number of days from the as_of day asked for, or null."
              },
              "status": {
                "type": "string",
                "enum": [
                  "upcoming",
                  "ended",
                  "in_effect",
                  "all"
                ],
                "description": "Which items by state: upcoming, ended, in_effect or all."
              },
              "sort": {
                "type": "string",
                "enum": [
                  "date",
                  "added",
                  "service"
                ],
                "description": "Order of the items."
              },
              "dir": {
                "type": "string",
                "enum": [
                  "asc",
                  "desc"
                ],
                "description": "Direction of the order."
              },
              "limit": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991,
                "description": "Most items in one answer."
              },
              "offset": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "description": "Number of matching items skipped."
              },
              "detail": {
                "type": "string",
                "enum": [
                  "compact",
                  "full"
                ],
                "description": "compact rows, or full records."
              }
            },
            "required": [
              "cloud",
              "type",
              "category",
              "service",
              "q",
              "from",
              "to",
              "within_days",
              "status",
              "sort",
              "dir",
              "limit",
              "offset",
              "detail"
            ],
            "additionalProperties": false,
            "description": "The query as it was understood: every parameter with the value that was used."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of items that match the query."
          },
          "status_counts": {
            "type": "object",
            "properties": {
              "upcoming": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "description": "Items it matches with status upcoming."
              },
              "ended": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "description": "Items it matches with status ended."
              },
              "in_effect": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991,
                "description": "Items it matches with status in_effect."
              }
            },
            "required": [
              "upcoming",
              "ended",
              "in_effect"
            ],
            "additionalProperties": false,
            "description": "Number of items the query matches in each status, with every other parameter as it was used. An empty list of upcoming items can stand next to items that have ended or are in effect: send status=all to list them."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of items in this answer."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9007199254740991,
            "description": "Most items one answer holds for this query."
          },
          "offset": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of matching items skipped before the first of this answer."
          },
          "next_offset": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              {
                "type": "null"
              }
            ],
            "description": "The offset of the next page, or null when this answer holds the last match."
          },
          "next_url": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ],
            "description": "Address of the next page of this list, at the data address, or null when this answer holds the last match."
          },
          "windows": {
            "description": "Only in the JSON form of the home page, never in an answer of the items address: the counts of the countdown strip of the page, in its order.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "enum": [
                    "due30",
                    "due90",
                    "due180",
                    "ended90"
                  ],
                  "description": "Identifier of the count: due30, due90, due180 or ended90."
                },
                "label": {
                  "type": "string",
                  "description": "Label of the count on the page."
                },
                "count": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of items in the window on the as_of day. Each count of items due includes the items due sooner."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "The data address that lists the items of the count: its total is count."
                },
                "next": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "description": "The words the page puts in front of the item, for example Next or Latest."
                        },
                        "slug": {
                          "type": "string",
                          "minLength": 1,
                          "description": "Stable identifier of the item. Never changes once published."
                        },
                        "title": {
                          "type": "string",
                          "description": "Short headline of the lifecycle change."
                        },
                        "effective_date": {
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                              "format": "date"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
                        },
                        "effective_precision": {
                          "type": "string",
                          "enum": [
                            "day",
                            "month",
                            "quarter",
                            "year"
                          ],
                          "description": "How exact effective_date is: day, month, quarter or year."
                        },
                        "url": {
                          "type": "string",
                          "format": "uri",
                          "description": "Page for this item on the site."
                        },
                        "markdown_url": {
                          "type": "string",
                          "format": "uri",
                          "description": "The same item as Markdown."
                        },
                        "json_url": {
                          "type": "string",
                          "format": "uri",
                          "description": "The same item as JSON."
                        }
                      },
                      "required": [
                        "label",
                        "slug",
                        "title",
                        "effective_date",
                        "effective_precision",
                        "url",
                        "markdown_url",
                        "json_url"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "The item the page names with the count, or null when it names none."
                }
              },
              "required": [
                "key",
                "label",
                "count",
                "url",
                "next"
              ],
              "additionalProperties": false
            }
          },
          "items": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/item_row"
                }
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/item"
                }
              }
            ],
            "description": "The items: compact rows, or whole records when detail is full."
          },
          "sections": {
            "description": "Only in the JSON form of the home page, a cloud page, a category page or a service page, never in an answer of the items address. For the home page, a cloud page and a category page: the other lists of items the page shows under its main list. For a service page: the lists the page sorts the items of the service into (upcoming, ended, in effect), so each row says where its item stands. Empty when the page shows no such list, with one exception: the three lists of the home page with no filter and the default window are always listed, also when the page shows none of them. A home view with a filter or another window has no other list.",
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Identifier of the list: the id of its heading on the page."
                },
                "heading": {
                  "type": "string",
                  "description": "Heading of the list on the page."
                },
                "total": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Number of items in the list. It is larger than the number of items here when the page shows only the first ones."
                },
                "url": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uri"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "A data address that answers the same items in the same order, or null when no data address does on the as_of day."
                },
                "items": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/item_row"
                  },
                  "description": "The items the page shows under the heading, as compact rows, in its order."
                }
              },
              "required": [
                "id",
                "heading",
                "total",
                "url",
                "items"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "generated_at",
          "as_of",
          "site",
          "license",
          "query",
          "total",
          "status_counts",
          "count",
          "limit",
          "offset",
          "next_offset",
          "next_url",
          "items"
        ],
        "additionalProperties": false
      },
      "items_export": {
        "type": "object",
        "properties": {
          "generated_at": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
            "format": "date-time",
            "description": "Moment this answer was built (ISO 8601, UTC)."
          },
          "site": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the site."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Address of the site."
              }
            },
            "required": [
              "name",
              "url"
            ],
            "additionalProperties": false,
            "description": "The site the data comes from."
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Number of items in the export."
          },
          "license": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the license, or the words that say none is chosen yet."
              },
              "url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Address of the license text, or null when there is none."
              },
              "note": {
                "type": "string",
                "description": "What that means for reuse of the data."
              }
            },
            "required": [
              "name",
              "url",
              "note"
            ],
            "additionalProperties": false,
            "description": "The license of the data."
          },
          "schema": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "enum": [
                "slug",
                "title",
                "summary",
                "cloud",
                "service",
                "service_slug",
                "category",
                "type",
                "announced_date",
                "effective_date",
                "effective_precision",
                "impact",
                "migration_path",
                "replacement",
                "affected_versions",
                "source_url",
                "extra_source_urls",
                "vendor_ref",
                "last_checked_at",
                "created_at",
                "updated_at",
                "url"
              ]
            },
            "additionalProperties": {
              "type": "string"
            },
            "required": [
              "slug",
              "title",
              "summary",
              "cloud",
              "service",
              "service_slug",
              "category",
              "type",
              "announced_date",
              "effective_date",
              "effective_precision",
              "impact",
              "migration_path",
              "replacement",
              "affected_versions",
              "source_url",
              "extra_source_urls",
              "vendor_ref",
              "last_checked_at",
              "created_at",
              "updated_at",
              "url"
            ],
            "description": "Each field name of an item with a one line description."
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Stable identifier of the item. Never changes once published."
                },
                "title": {
                  "type": "string",
                  "description": "Short headline of the lifecycle change."
                },
                "summary": {
                  "type": "string",
                  "description": "One or two plain sentences describing the change."
                },
                "cloud": {
                  "type": "string",
                  "enum": [
                    "azure",
                    "aws",
                    "gcp",
                    "oci",
                    "multi"
                  ],
                  "description": "Cloud the item belongs to: azure, aws, gcp, oci or multi."
                },
                "service": {
                  "type": "string",
                  "description": "Display name of the affected service."
                },
                "service_slug": {
                  "type": "string",
                  "minLength": 1,
                  "description": "URL-safe identifier of the service."
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "service",
                    "feature",
                    "kubernetes",
                    "runtime",
                    "database",
                    "compute_sku",
                    "os_image",
                    "api_sdk",
                    "iac_provider",
                    "iac_module",
                    "iac_language",
                    "other"
                  ],
                  "description": "Kind of thing affected, for example service, runtime, kubernetes or database."
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "retirement",
                    "end_of_support",
                    "breaking_change"
                  ],
                  "description": "Kind of change: retirement, end_of_support or breaking_change."
                },
                "announced_date": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                      "format": "date"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Date the vendor announced the change (YYYY-MM-DD), or null when not stated."
                },
                "effective_date": {
                  "anyOf": [
                    {
                      "type": "string",
                      "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                      "format": "date"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "description": "Date the change takes effect (YYYY-MM-DD), or null when not announced. For month, quarter and year precision this is the first day of the period."
                },
                "effective_precision": {
                  "type": "string",
                  "enum": [
                    "day",
                    "month",
                    "quarter",
                    "year"
                  ],
                  "description": "How exact effective_date is: day, month, quarter or year."
                },
                "impact": {
                  "type": "string",
                  "description": "What stops working and who is affected."
                },
                "migration_path": {
                  "type": "string",
                  "description": "Steps to take before the effective date. May contain Markdown."
                },
                "replacement": {
                  "description": "Recommended replacement, or null when the vendor names none.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "affected_versions": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Versions affected. Array in JSON, joined with \"; \" in CSV."
                },
                "source_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page the item was verified against: an official vendor page, or the endoflife.date page for the few products where it is the only source of the date."
                },
                "extra_source_urls": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": "Additional sources: official pages, or an endoflife.date page. Array in JSON, joined with \"; \" in CSV."
                },
                "vendor_ref": {
                  "description": "Vendor reference for the announcement, or null.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "last_checked_at": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
                  "format": "date-time",
                  "description": "Timestamp (ISO 8601, UTC) of the last successful recheck against the source."
                },
                "created_at": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
                  "format": "date-time",
                  "description": "Timestamp (ISO 8601, UTC) when the item was first published here."
                },
                "updated_at": {
                  "type": "string",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?Z$",
                  "format": "date-time",
                  "description": "Timestamp (ISO 8601, UTC) of the last change to the item."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Page for this item on the site."
                }
              },
              "required": [
                "slug",
                "title",
                "summary",
                "cloud",
                "service",
                "service_slug",
                "category",
                "type",
                "announced_date",
                "effective_date",
                "effective_precision",
                "impact",
                "migration_path",
                "replacement",
                "affected_versions",
                "source_url",
                "extra_source_urls",
                "vendor_ref",
                "last_checked_at",
                "created_at",
                "updated_at",
                "url"
              ],
              "additionalProperties": false
            },
            "description": "Every published item."
          }
        },
        "required": [
          "generated_at",
          "site",
          "count",
          "license",
          "schema",
          "items"
        ],
        "additionalProperties": false
      }
    },
    "responses": {
      "invalid_parameter": {
        "description": "A query parameter has a value that is not allowed, or the name of a row field was sent as a parameter (state, service_slug, slug). The answer names the parameter and what it accepts, or says what to use.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/error"
            }
          }
        }
      },
      "not_found": {
        "description": "This page does not exist. The item may have been renamed or withdrawn, or the link may be incomplete. Search for it, or start from the timeline. Search the items: https://eolwatch.dev/data/items.json?status=all&q= followed by your words. The timeline: https://eolwatch.dev/index.json",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/error"
            }
          }
        }
      },
      "gone": {
        "description": "This item was withdrawn. The vendor changed or canceled the announcement, or the entry was wrong, so the item is no longer listed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/error"
            }
          }
        }
      },
      "not_found_markdown": {
        "description": "This page does not exist. The item may have been renamed or withdrawn, or the link may be incomplete. Search for it, or start from the timeline.",
        "content": {
          "text/markdown": {
            "schema": {
              "type": "string"
            }
          }
        }
      },
      "gone_markdown": {
        "description": "This item was withdrawn. The vendor changed or canceled the announcement, or the entry was wrong, so the item is no longer listed.",
        "content": {
          "text/markdown": {
            "schema": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}
