{
  "openapi": "3.0.3",
  "info": {
    "title": "Weather Oracle API",
    "version": "0.3.0",
    "description": "Probabilistic daily maximum-temperature forecasts for the 51 cities behind Polymarket weather markets. Multi-model ensemble (ECMWF/GFS/ICON/Meteo-France/UKMO) with seasonal per-model bias correction, refreshed hourly. Bucket probabilities on the integer-degree grid (1°C international / 2°F US). Pay-per-request via x402 (USDC on Base) — no accounts, no API keys. Free catalog at /markets."
  },
  "servers": [{ "url": "https://91-197-235-206.sslip.io" }],
  "paths": {
    "/markets": {
      "get": {
        "operationId": "listMarkets",
        "summary": "Free catalog: stations, units, products, prices, next update time",
        "responses": {
          "200": { "description": "Catalog of sellable city markets (JSON)" }
        }
      }
    },
    "/accuracy": {
      "get": {
        "operationId": "getAccuracy",
        "summary": "Free verifiable track record: 30-day MAE and hit rates per station, honest morning-lead ruler (no leakage)",
        "responses": {
          "200": { "description": "Per-station accuracy of the exact product sold (bias-corrected center at 5-14h lead) vs observed daily max" }
        }
      }
    },
    "/forecast/{station}/point": {
      "get": {
        "operationId": "getPointForecast",
        "summary": "Expected daily max temperature (median) with 80% interval",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.005" }
        },
        "parameters": [
          {
            "name": "station",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "SBGR",
            "description": "ICAO station code (e.g. SBGR = São Paulo, KNYC = New York). Full list at /markets."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Target date, YYYY-MM-DD (today or tomorrow, city-local). Defaults to today."
          }
        ],
        "responses": {
          "200": { "description": "point_c (median max), interval80_c, sigma_c, model_ts" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    },
    "/forecast/all/buckets": {
      "get": {
        "operationId": "getAllBuckets",
        "summary": "Bundle: market-mirrored bucket probabilities for ALL 51 cities in one call",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.30" }
        },
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Target date, YYYY-MM-DD (today through day+3, city-local). Defaults to each city's local today."
          }
        ],
        "responses": {
          "200": { "description": "cities[] each with market-mirrored buckets (outcome label, YES clobTokenId, p)" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    },
    "/forecast/{station}/buckets": {
      "get": {
        "operationId": "getBucketProbabilities",
        "summary": "Probability per ACTUAL Polymarket outcome range, with YES clobTokenIds (market-mirrored; falls back to integer-degree grid if market not yet listed)",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.02" }
        },
        "parameters": [
          {
            "name": "station",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "SBGR",
            "description": "ICAO station code (e.g. SBGR = São Paulo, KNYC = New York). Full list at /markets."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Target date, YYYY-MM-DD (today or tomorrow, city-local). Defaults to today."
          }
        ],
        "responses": {
          "200": { "description": "buckets[] with {range, p}, center_c, sigma_c, model_ts" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    },
    "/forecast/{station}/ensemble": {
      "get": {
        "operationId": "getEnsembleMembers",
        "summary": "Raw per-model forecast maxima (ECMWF/GFS/ICON/Meteo-France/UKMO) with spread — read model disagreement yourself",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.01" }
        },
        "parameters": [
          {
            "name": "station",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "SBGR",
            "description": "ICAO station code (e.g. SBGR = São Paulo, KNYC = New York). Full list at /markets."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Target date, YYYY-MM-DD (today through day+3, city-local). Defaults to today."
          }
        ],
        "responses": {
          "200": { "description": "models_c per model, n_models, spread_c, center_c, sigma_c" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    },
    "/climate/{station}": {
      "get": {
        "operationId": "getClimatology",
        "summary": "Station climatology 2021+: monthly percentiles of daily max, records, historical ceiling",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.02" }
        },
        "parameters": [
          {
            "name": "station",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "SBGR",
            "description": "ICAO station code (e.g. SBGR = São Paulo, KNYC = New York). Full list at /markets."
          }
        ],
        "responses": {
          "200": { "description": "months{1..12} with percentiles p05..p95 of daily max, records; all-time record" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    },
    "/forecast/{station}/distribution": {
      "get": {
        "operationId": "getFullDistribution",
        "summary": "Full CDF of daily max temperature on a 0.1°C grid (for custom sizing)",
        "x-payment-info": {
          "protocols": ["x402"],
          "price": { "mode": "fixed", "currency": "USD", "amount": "0.05" }
        },
        "parameters": [
          {
            "name": "station",
            "in": "path",
            "required": true,
            "schema": { "type": "string" },
            "example": "SBGR",
            "description": "ICAO station code (e.g. SBGR = São Paulo, KNYC = New York). Full list at /markets."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Target date, YYYY-MM-DD (today or tomorrow, city-local). Defaults to today."
          }
        ],
        "responses": {
          "200": { "description": "cdf_c grid [[temp_c, cdf], ...], center_c, sigma_c" },
          "402": { "description": "x402 payment required — USDC on Base" }
        }
      }
    }
  }
}
