{
  "openapi": "3.1.0",
  "info": {
    "title": "Lumavik aurora data API",
    "version": "1.0.0",
    "summary": "Auroral visibility thresholds, city latitudes, darkness by month, glossary and sources, as JSON.",
    "description": "A read-only, keyless, CORS-open API over the datasets this site publishes. The arithmetic behind it is the same module the browser calculators on lumavik.org run, and the tables are the ones the articles print, so the API and the pages cannot disagree.\n\nWhat it is not: live. It says what a location needs before the aurora is worth looking for. What the Sun is doing right now comes from NOAA SWPC, whose endpoints are listed in /api/v1/sources.json.\n\nReuse is licensed CC BY 4.0 with a link back.",
    "contact": {
      "name": "Lumavik support",
      "email": "support@lumavik.org",
      "url": "https://lumavik.org/contact/"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    },
    "termsOfService": "https://lumavik.org/terms/"
  },
  "servers": [
    {
      "url": "https://lumavik.org/api/v1",
      "description": "Static origin behind Cloudflare"
    }
  ],
  "paths": {
    "/visibility.json": {
      "get": {
        "operationId": "getVisibilityThresholds",
        "summary": "Oval-edge model, NOAA storm scale and viewing bands",
        "description": "The Kp at which the modelled auroral oval reaches each geomagnetic latitude, the NOAA G-level for each Kp with its published average frequency per solar cycle, and the editorial \"worth watching\" bands. Read the `caveats` array before quoting a threshold.",
        "responses": {
          "200": {
            "description": "Thresholds and model",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Visibility"
                }
              }
            }
          }
        }
      }
    },
    "/cities.json": {
      "get": {
        "operationId": "getCities",
        "summary": "Aurora-viewing locations with both Kp thresholds",
        "responses": {
          "200": {
            "description": "Cities",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CityList"
                }
              }
            }
          }
        }
      }
    },
    "/darkness.json": {
      "get": {
        "operationId": "getDarkness",
        "summary": "Astronomical darkness by latitude and month, plus the season windows",
        "responses": {
          "200": {
            "description": "Darkness model",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/glossary.json": {
      "get": {
        "operationId": "getGlossary",
        "summary": "Aurora and space-weather terms, one self-contained sentence each",
        "responses": {
          "200": {
            "description": "Glossary",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/sources.json": {
      "get": {
        "operationId": "getSources",
        "summary": "Primary sources behind every figure, and the live NOAA feeds",
        "responses": {
          "200": {
            "description": "Sources",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/status.json": {
      "get": {
        "operationId": "getStatus",
        "summary": "Freshness of the published datasets",
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Visibility": {
        "type": "object",
        "required": [
          "oval_edge_by_kp",
          "viewing_bands"
        ],
        "properties": {
          "model": {
            "type": "object",
            "description": "The geomagnetic pole and twilight threshold every derived figure uses."
          },
          "caveats": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "oval_edge_by_kp": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OvalEdgeRow"
            }
          },
          "viewing_bands": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ViewingBand"
            }
          },
          "forecast_products": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "emission_by_altitude": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "OvalEdgeRow": {
        "type": "object",
        "required": [
          "kp",
          "oval_edge_geomagnetic_latitude"
        ],
        "properties": {
          "kp": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9,
            "examples": [
              5
            ]
          },
          "oval_edge_geomagnetic_latitude": {
            "type": "number",
            "description": "Approximate equatorward edge of the auroral oval at this Kp, in geomagnetic degrees. A modelled ring, not a boundary, and it moves inside a single three-hour Kp interval.",
            "examples": [
              56.3
            ]
          },
          "noaa_storm_level": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "G1"
            ],
            "description": "Null below Kp 5: half the scale carries no storm label."
          },
          "noaa_storm_name": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "Minor"
            ]
          },
          "average_events_per_solar_cycle": {
            "type": [
              "integer",
              "null"
            ],
            "description": "NOAA's published long-run average per 11-year cycle. An average, never a schedule.",
            "examples": [
              1700
            ]
          }
        }
      },
      "ViewingBand": {
        "type": "object",
        "properties": {
          "geomagnetic_latitude": {
            "type": "string",
            "examples": [
              "55–60°"
            ]
          },
          "kp_from": {
            "type": "integer",
            "examples": [
              5
            ]
          },
          "kp_to": {
            "type": "integer",
            "examples": [
              7
            ]
          },
          "means": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CityList": {
        "type": "object",
        "properties": {
          "cities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/City"
            }
          }
        }
      },
      "City": {
        "type": "object",
        "required": [
          "city",
          "geographic_latitude"
        ],
        "properties": {
          "city": {
            "type": "string",
            "examples": [
              "Minneapolis"
            ]
          },
          "country": {
            "type": "string"
          },
          "hemisphere": {
            "type": "string",
            "enum": [
              "north",
              "south"
            ]
          },
          "geographic_latitude": {
            "type": "number",
            "examples": [
              45
            ]
          },
          "corrected_geomagnetic_latitude": {
            "type": [
              "object",
              "null"
            ],
            "description": "Approximate CGM range as published on the source page. Null for southern towns, where a verifiable southern CGM value was not available and none is invented."
          },
          "kp_oval_overhead": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Kp at which the modelled oval reaches roughly overhead. Null means even Kp 9 does not. This is the HIGHER of the two thresholds. There are two different \"Kp you need\" numbers and confusing them is the most common error made with this data. `kp_oval_overhead` is the Kp at which the modelled auroral oval expands far enough for emission to be produced roughly above that location. `kp_visible_from_area` is the editorial estimate of when a display becomes worth going outside for from there, which is lower, because emission around 100 km up has a geometric horizon of about 1100 km and is routinely seen on the poleward horizon by people far outside the oval. Quote whichever you mean, and say which.",
            "examples": [
              7
            ]
          },
          "kp_visible_from_area": {
            "type": [
              "object",
              "null"
            ],
            "description": "The source page's own estimate of when a display becomes visible from the area, including on the poleward horizon. The LOWER of the two thresholds."
          },
          "dark_hours_midwinter": {
            "type": "number",
            "description": "Hours with the sun more than 18 degrees below the horizon at the local winter solstice."
          },
          "dark_hours_midsummer": {
            "type": "number",
            "description": "Zero means the sky never gets astronomically dark; the season is closed whatever Kp does."
          },
          "source": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Glossary": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "terms": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "term": {
                  "type": "string",
                  "examples": [
                    "Auroral oval"
                  ]
                },
                "definition": {
                  "type": "string"
                },
                "source": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "Sources": {
        "type": "object",
        "properties": {
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "examples": [
                    "gfzKp"
                  ]
                },
                "title": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string",
                  "examples": [
                    "NOAA SWPC"
                  ]
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                },
                "verified": {
                  "type": "string",
                  "format": "date"
                }
              }
            }
          },
          "live_data": {
            "type": "array",
            "description": "Keyless, CORS-open NOAA endpoints carrying current conditions. Fetch them directly.",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "Status": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Human-readable API documentation",
    "url": "https://lumavik.org/api/"
  },
  "x-endpoints": {
    "index": "https://lumavik.org/api/v1/index.json",
    "openapi": "https://lumavik.org/api/v1/openapi.json",
    "status": "https://lumavik.org/api/v1/status.json",
    "visibility": "https://lumavik.org/api/v1/visibility.json",
    "cities": "https://lumavik.org/api/v1/cities.json",
    "darkness": "https://lumavik.org/api/v1/darkness.json",
    "glossary": "https://lumavik.org/api/v1/glossary.json",
    "sources": "https://lumavik.org/api/v1/sources.json"
  }
}
