{
  "openapi": "3.1.1",
  "info": {
    "title": "Internet Archive Change Explorer API",
    "version": "1.0.0",
    "summary": "See how a web page changed in the Wayback Machine: capture timeline plus the changes that matter.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://internetarchivechangeexplorer.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "See how a web page changed in the Wayback Machine: capture timeline plus the changes that matter.",
        "description": "Lists the distinct Wayback Machine captures of a URL, picks the captures closest to two dates (or exact timestamps), fetches both raw archived versions and diffs them, ranking meaningful changes — prices, headings, legal/policy terms, dates, contacts, links — above noise. Paste CDX rows and two HTML versions to analyse offline.\n\nMethodology:\n- Capture list: Wayback CDX API GET https://web.archive.org/cdx/search/cdx?url=…&output=json&fl=timestamp,original,statuscode,digest,length,mimetype&filter=statuscode:200&filter=mimetype:text/html, one capture per day (collapse=timestamp:8) — or per month for spans over 900 days. A new \"version\" starts whenever the content digest (SHA-1) changes.\n- Capture selection: exact 14-digit timestamps if given, otherwise the successful HTML capture closest to each date, taken from the timeline query (from = before − 30 days, to = after + 30 days); only if that is empty does the tool fall back to CDX closest=…&sort=closest&limit=1.\n- Archived pages are fetched raw (without the Wayback toolbar or URL rewriting) from https://web.archive.org/web/<timestamp>id_/<original URL>. Identical digests skip the fetch.\n- The two versions are compared with the Website Change Explainer engine: block-level LCS diff, word diffs, and rule-based categories (price, legal/policy terms, contact, link target, title, date, heading, number) ranked above trivial noise (whitespace, timestamps, copyright years, tracking parameters).\n- Similarity is the Dice coefficient over the words of the extracted page text (htmlToText).\n- Caveats: digests also change for http/https/www variants, embedded tokens or ads; the archive may miss periods; content loaded by JavaScript after page load is usually not in the raw HTML.",
        "tags": [
          "public-data"
        ],
        "x-mcp-tool": "internet_archive_change_explorer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InternetArchiveChangeExplorerInput"
              },
              "examples": {
                "example1": {
                  "summary": "example.com: Aug 2025 vs Sep 2026 (pasted CDX rows + archived HTML)",
                  "value": {
                    "url": "https://example.com/",
                    "beforeTimestamp": "20250801002042",
                    "afterTimestamp": "20260901000146",
                    "maxCaptures": 40,
                    "maxChanges": 25,
                    "pastedCdx": "[[\"timestamp\",\"original\",\"statuscode\",\"digest\",\"length\",\"mimetype\"],[\"20240701002435\",\"http://www.example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"699\",\"text/html\"],[\"20240801010121\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"751\",\"text/html\"],[\"20240901000219\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"1074\",\"text/html\"],[\"20241001000436\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"713\",\"text/html\"],[\"20241101002130\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"711\",\"text/html\"],[\"20241201001928\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"1263\",\"text/html\"],[\"20250101004557\",\"https://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"1232\",\"text/html\"],[\"20250201012603\",\"http://user:pass@example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"1202\",\"text/html\"],[\"20250301003025\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"1211\",\"text/html\"],[\"20250401000301\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"745\",\"text/html\"],[\"20250501001414\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"740\",\"text/html\"],[\"20250601000522\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"743\",\"text/html\"],[\"20250701005008\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"746\",\"text/html\"],[\"20250801002042\",\"http://example.com/\",\"200\",\"JI6OR3QR4CI526JD6TMMNZNV4QPMPQCH\",\"737\",\"text/html\"],[\"20250901000034\",\"https://example.com/\",\"200\",\"YXWQ7LLPPIZ7CVO6DVQ4U3Y2IO5M42AG\",\"1345\",\"text/html\"],[\"20251001001217\",\"https://example.com/\",\"200\",\"YXWQ7LLPPIZ7CVO6DVQ4U3Y2IO5M42AG\",\"1375\",\"text/html\"],[\"20251101000454\",\"https://www.example.com/\",\"200\",\"JUWMXAQNHPTRTHYQWT3EJILYCL7YC3PQ\",\"961\",\"text/html\"],[\"20251201000848\",\"http://www.example.com/\",\"200\",\"JUWMXAQNHPTRTHYQWT3EJILYCL7YC3PQ\",\"937\",\"text/html\"],[\"20260101000936\",\"http://www.example.com/\",\"200\",\"JUWMXAQNHPTRTHYQWT3EJILYCL7YC3PQ\",\"1009\",\"text/html\"],[\"20260201000022\",\"https://example.com/\",\"200\",\"4N5T7URO6PDNDBFG3V3AAQ45MXR3EXWK\",\"1040\",\"text/html\"],[\"20260301000114\",\"https://example.com/\",\"200\",\"UB6ILJGAIGCZBRVPWK2UVEWKHOYWSIYT\",\"1054\",\"text/html\"],[\"20260401000016\",\"https://example.com/\",\"200\",\"M7CPWPJVRUMERYFUWXWAHQRA4HOEEEXZ\",\"1042\",\"text/html\"],[\"20260501000121\",\"https://example.com/\",\"200\",\"M7CPWPJVRUMERYFUWXWAHQRA4HOEEEXZ\",\"1041\",\"text/html\"],[\"20260601000130\",\"https://example.com/\",\"200\",\"M7CPWPJVRUMERYFUWXWAHQRA4HOEEEXZ\",\"1041\",\"text/html\"],[\"20260701000143\",\"https://example.com/\",\"200\",\"PKUMGV5XIIUJG5CKD4HZMCRWKUMVP5S6\",\"1050\",\"text/html\"],[\"20260801000202\",\"https://example.com/\",\"200\",\"PKUMGV5XIIUJG5CKD4HZMCRWKUMVP5S6\",\"1049\",\"text/html\"],[\"20260901000146\",\"https://example.com/\",\"200\",\"PKUMGV5XIIUJG5CKD4HZMCRWKUMVP5S6\",\"1050\",\"text/html\"]]",
                    "pastedBefore": "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 2em;\n        background-color: #fdfdff;\n        border-radius: 0.5em;\n        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        div {\n            margin: 0 auto;\n            width: auto;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is for use in illustrative examples in documents. You may use this\n    domain in literature without prior coordination or asking for permission.</p>\n    <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n",
                    "pastedAfter": "<!doctype html><html lang=\"en\"><head><title>Example Domain</title><link rel=\"icon\" href=\"data:,\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><style>body{background:#eee;width:60vw;margin:15vh auto;font-family:system-ui,sans-serif}h1{font-size:1.5em}div{opacity:0.8}a:link,a:visited{color:#348}</style></head><body><div><h1>Example Domain</h1><p>This domain is for use in documentation examples without needing permission. Avoid use in operations.</p><p><a href=\"https://iana.org/domains/example\">Learn more</a></p></div></body></html>\n"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InternetArchiveChangeExplorerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "InternetArchiveChangeExplorerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "title": "Page URL",
            "type": "string",
            "format": "uri"
          },
          "beforeDate": {
            "title": "Before date",
            "description": "The capture closest to this date is used. Default: one year ago.",
            "type": "string",
            "format": "date"
          },
          "afterDate": {
            "title": "After date",
            "description": "Default: today (latest capture).",
            "type": "string",
            "format": "date"
          },
          "beforeTimestamp": {
            "title": "Exact \"before\" capture (14-digit timestamp)",
            "type": "string",
            "maxLength": 14
          },
          "afterTimestamp": {
            "title": "Exact \"after\" capture (14-digit timestamp)",
            "type": "string",
            "maxLength": 14
          },
          "maxCaptures": {
            "title": "Captures shown in the timeline",
            "type": "integer",
            "minimum": 5,
            "maximum": 200,
            "default": 40
          },
          "maxChanges": {
            "title": "Max changes listed",
            "type": "integer",
            "minimum": 5,
            "maximum": 200,
            "default": 25
          },
          "pastedCdx": {
            "title": "Pasted CDX output (offline)",
            "description": "output=json rows or default text lines.",
            "type": "string",
            "maxLength": 2000000
          },
          "pastedBefore": {
            "title": "Pasted \"before\" HTML (offline)",
            "type": "string",
            "maxLength": 400000
          },
          "pastedAfter": {
            "title": "Pasted \"after\" HTML (offline)",
            "type": "string",
            "maxLength": 400000
          }
        },
        "required": []
      },
      "InternetArchiveChangeExplorerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "url",
              "before",
              "after",
              "captures",
              "identical",
              "comparison",
              "highlights",
              "unifiedDiff"
            ],
            "properties": {
              "url": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "before": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "timestamp",
                  "time",
                  "original",
                  "digest",
                  "archiveUrl",
                  "rawUrl",
                  "selectedBy"
                ],
                "properties": {
                  "timestamp": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "time": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "original": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "digest": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "archiveUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "rawUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "selectedBy": {
                    "type": "string",
                    "enum": [
                      "nearest-capture",
                      "explicit-timestamp",
                      "pasted"
                    ]
                  }
                }
              },
              "after": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "timestamp",
                  "time",
                  "original",
                  "digest",
                  "archiveUrl",
                  "rawUrl",
                  "selectedBy"
                ],
                "properties": {
                  "timestamp": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "time": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "original": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "digest": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "archiveUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "rawUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "selectedBy": {
                    "type": "string",
                    "enum": [
                      "nearest-capture",
                      "explicit-timestamp",
                      "pasted"
                    ]
                  }
                }
              },
              "captures": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "total",
                  "distinctVersions",
                  "granularity",
                  "items"
                ],
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "distinctVersions": {
                    "type": "integer"
                  },
                  "granularity": {
                    "type": "string"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "timestamp",
                        "time",
                        "original",
                        "statuscode",
                        "digest",
                        "length",
                        "newVersion"
                      ],
                      "properties": {
                        "timestamp": {
                          "type": "string"
                        },
                        "time": {
                          "type": "string"
                        },
                        "original": {
                          "type": "string"
                        },
                        "statuscode": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "digest": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "length": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "newVersion": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              },
              "identical": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "true when both captures have the same content digest (no fetch needed)."
              },
              "comparison": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "similarityPct",
                  "wordsBefore",
                  "wordsAfter",
                  "meaningful",
                  "trivial",
                  "high",
                  "medium",
                  "low"
                ],
                "properties": {
                  "similarityPct": {
                    "type": "number"
                  },
                  "wordsBefore": {
                    "type": "integer"
                  },
                  "wordsAfter": {
                    "type": "integer"
                  },
                  "meaningful": {
                    "type": "integer"
                  },
                  "trivial": {
                    "type": "integer"
                  },
                  "high": {
                    "type": "integer"
                  },
                  "medium": {
                    "type": "integer"
                  },
                  "low": {
                    "type": "integer"
                  }
                }
              },
              "highlights": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "category",
                    "level",
                    "kind",
                    "element",
                    "before",
                    "after",
                    "wordDiff"
                  ],
                  "properties": {
                    "category": {
                      "type": "string"
                    },
                    "level": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string"
                    },
                    "element": {
                      "type": "string"
                    },
                    "before": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "after": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "wordDiff": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "unifiedDiff": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}