{
  "openapi": "3.1.1",
  "info": {
    "title": "DataFresh API",
    "version": "1.0.0",
    "summary": "Is this dataset or API still fresh? Newest record, update cadence check and schema drift.",
    "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://datafresh.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Is this dataset or API still fresh? Newest record, update cadence check and schema drift.",
        "description": "Point DataFresh at a public JSON or CSV endpoint (or paste the content). It finds the records, infers a schema with a stable fingerprint, finds the newest timestamp, compares its age with the update cadence you expect, and reports schema changes since the last check – as one of: healthy, stale, schema_changed, unavailable, no_timestamp.\n\nMethodology:\n- Records: a JSON root array, or the largest array of objects within 3 levels; CSV uses the first row as header (comma or semicolon).\n- Schema: every field (one nesting level flattened as parent.child) with its observed value types and presence ratio; the fingerprint is the first 16 hex chars of SHA-256 over sorted \"field:types\" lines.\n- Timestamp: the field you name, otherwise the first field named like updated/modified/timestamp/date/time/year where ≥ 80% of values parse as dates (ISO 8601, epoch s/ms, YYYY, YYYY-Qn, DD.MM.YYYY). Years count as 31 Dec, quarters as their last day.\n- Freshness: age = now − newest timestamp. healthy if age ≤ 1.5 × expected interval, otherwise stale. Without a timestamp field the HTTP Last-Modified header is used if present.\n- Drift: compared with the previous schema you paste or, with \"remember\", the schema stored for the same URL (key = SHA-256 of the URL). Any added/removed field or type change → schema_changed (takes precedence over healthy, not over unavailable).",
        "tags": [
          "developer"
        ],
        "x-mcp-tool": "datafresh",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DatafreshInput"
              },
              "examples": {
                "example1": {
                  "summary": "Stale daily feed",
                  "value": {
                    "content": "{\"meta\":{\"source\":\"example\"},\"items\":[{\"id\":1,\"value\":3.2,\"updated_at\":\"2026-10-01T06:00:00Z\"},{\"id\":2,\"value\":4.1,\"updated_at\":\"2026-10-03T06:00:00Z\"}]}",
                    "expectedCadenceHours": 24
                  }
                },
                "example2": {
                  "summary": "Yearly CSV with schema change",
                  "value": {
                    "content": "country;year;value\nDE;2024;2.5\nFR;2025;2.1",
                    "expectedCadenceHours": 8760,
                    "previousSchema": "{\"country\":{\"types\":[\"string\"],\"presence\":1},\"year\":{\"types\":[\"number\"],\"presence\":1},\"value\":{\"types\":[\"number\"],\"presence\":1},\"unit\":{\"types\":[\"string\"],\"presence\":1}}"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatafreshResult"
                }
              }
            }
          },
          "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"
                }
              }
            }
          }
        }
      },
      "DatafreshInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "title": "Dataset or API URL",
            "description": "Public http(s) JSON or CSV, max 2 MiB.",
            "type": "string",
            "format": "uri"
          },
          "content": {
            "title": "Or paste JSON/CSV content",
            "type": "string",
            "maxLength": 2000000
          },
          "format": {
            "title": "Format",
            "type": "string",
            "enum": [
              "auto",
              "json",
              "csv"
            ],
            "default": "auto"
          },
          "timestampField": {
            "title": "Timestamp field (optional)",
            "description": "Leave empty to detect (updated_at, date, …). Nested: parent.child",
            "type": "string",
            "maxLength": 120
          },
          "expectedCadenceHours": {
            "title": "Expected update interval",
            "description": "24 = daily, 168 = weekly, 720 ≈ monthly, 8760 = yearly.",
            "type": "number",
            "minimum": 0.1,
            "maximum": 87600,
            "default": 24,
            "x-unit": "hours"
          },
          "previousSchema": {
            "title": "Previous schema (optional, JSON from an earlier result)",
            "type": "string",
            "maxLength": 200000
          },
          "remember": {
            "title": "Remember this URL's schema for the next check",
            "description": "Stores only a hash of the URL plus the field list.",
            "type": "boolean",
            "default": true
          }
        },
        "required": []
      },
      "DatafreshResult": {
        "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": [
              "status",
              "source",
              "records",
              "recordPath",
              "timestampField",
              "newestRecordAt",
              "ageHours",
              "expectedCadenceHours",
              "schema",
              "schemaFingerprint",
              "previousFingerprint",
              "drift",
              "httpLastModified"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "healthy",
                  "stale",
                  "schema_changed",
                  "unavailable",
                  "no_timestamp"
                ]
              },
              "source": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "url",
                  "httpStatus",
                  "fetchedAt",
                  "format"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "url",
                      "pasted"
                    ]
                  },
                  "url": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "httpStatus": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "fetchedAt": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "json",
                      "csv"
                    ]
                  }
                }
              },
              "records": {
                "type": "integer"
              },
              "recordPath": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "timestampField": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "newestRecordAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "ageHours": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "expectedCadenceHours": {
                "type": "number"
              },
              "httpLastModified": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "schema": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "types",
                    "presence"
                  ],
                  "properties": {
                    "types": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "presence": {
                      "type": "number"
                    }
                  }
                }
              },
              "schemaFingerprint": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "previousFingerprint": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "drift": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "added",
                  "removed",
                  "typeChanged"
                ],
                "properties": {
                  "added": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "removed": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "typeChanged": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "field",
                        "before",
                        "after"
                      ],
                      "properties": {
                        "field": {
                          "type": "string"
                        },
                        "before": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "after": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      }
    }
  }
}