{
  "openapi": "3.0.3",
  "info": {
    "title": "UV Index API",
    "version": "1.0.0",
    "summary": "Real-time UV index, hourly forecast and monthly history for cities worldwide.",
    "description": "The UV Index API by uvindex.io returns the live UV index, hourly forecast and monthly historical UV for any of thousands of cities worldwide, colour-coded by the WHO risk scale. Ideal for weather, health, sun-safety, vitamin-D and travel apps.\n\n**Authentication.** Send your API token as a Bearer token: `Authorization: Bearer YOUR_TOKEN`.\n\n**Free tier & rate limit.** Free to use, rate limited to **60 requests per minute** per token. A `429 Too Many Requests` is returned when exceeded.\n\n**Cities** are addressed by their URL slug (`cityname`), e.g. `istanbul`, `new-york`, `sydney`.",
    "termsOfService": "https://uvindex.io/privacy-policy",
    "contact": {
      "name": "uvindex.io",
      "url": "https://uvindex.io/contact"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    }
  },
  "externalDocs": {
    "description": "API documentation",
    "url": "https://uvindex.io/api"
  },
  "servers": [
    { "url": "https://uvindex.io/api/v1", "description": "Production" }
  ],
  "security": [{ "bearerAuth": [] }],
  "tags": [
    { "name": "UV", "description": "UV index by city (weather / sun safety)" }
  ],
  "paths": {
    "/uv/{cityname}": {
      "get": {
        "tags": ["UV"],
        "operationId": "getCurrentUv",
        "summary": "Current UV index for a city",
        "description": "Returns the live UV index for a city, plus today's peak (`uv_max`) and the WHO risk band.",
        "parameters": [{ "$ref": "#/components/parameters/Cityname" }],
        "responses": {
          "200": {
            "description": "Current UV index",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CurrentResponse" },
                "example": {
                  "data": {
                    "city": "Istanbul",
                    "cityname": "istanbul",
                    "country": "Turkey",
                    "lat": 41.0108,
                    "lng": 28.9482,
                    "uv": 6.2,
                    "uv_time": "2026-07-03T11:00:00+00:00",
                    "uv_max": 8.1,
                    "uv_max_time": "2026-07-03T12:30:00+00:00",
                    "risk_level": "High"
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/uv/{cityname}/forecast": {
      "get": {
        "tags": ["UV"],
        "operationId": "getUvForecast",
        "summary": "Hourly UV forecast for a city",
        "description": "Returns the hourly UV forecast for the day for a city.",
        "parameters": [{ "$ref": "#/components/parameters/Cityname" }],
        "responses": {
          "200": {
            "description": "Hourly UV forecast",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ForecastResponse" },
                "example": {
                  "data": {
                    "city": "Istanbul",
                    "cityname": "istanbul",
                    "country": "Turkey",
                    "lat": 41.0108,
                    "lng": 28.9482,
                    "forecast": [
                      { "uv": 0.1, "uv_time": "2026-07-03T04:00:00+00:00" },
                      { "uv": 3.4, "uv_time": "2026-07-03T08:00:00+00:00" },
                      { "uv": 8.1, "uv_time": "2026-07-03T12:30:00+00:00" }
                    ]
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/uv/{cityname}/history": {
      "get": {
        "tags": ["UV"],
        "operationId": "getUvHistory",
        "summary": "Monthly UV history for a city",
        "description": "Returns the average UV index by month over the past year for a city, keyed by ISO date.",
        "parameters": [{ "$ref": "#/components/parameters/Cityname" }],
        "responses": {
          "200": {
            "description": "Monthly UV history",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/HistoryResponse" },
                "example": {
                  "data": {
                    "city": "Istanbul",
                    "cityname": "istanbul",
                    "country": "Turkey",
                    "lat": 41.0108,
                    "lng": 28.9482,
                    "history": {
                      "2025-08-15T12:00:00.000Z": 8,
                      "2025-09-15T12:00:00.000Z": 6,
                      "2025-10-15T12:00:00.000Z": 4
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API token issued to your uvindex.io account. Send as `Authorization: Bearer YOUR_TOKEN`."
      }
    },
    "parameters": {
      "Cityname": {
        "name": "cityname",
        "in": "path",
        "required": true,
        "description": "City URL slug (lowercase, hyphenated), e.g. `istanbul`, `new-york`, `sydney`.",
        "schema": { "type": "string", "example": "istanbul" }
      }
    },
    "schemas": {
      "CityBase": {
        "type": "object",
        "properties": {
          "city": { "type": "string", "example": "Istanbul" },
          "cityname": { "type": "string", "example": "istanbul" },
          "country": { "type": "string", "example": "Turkey" },
          "lat": { "type": "number", "format": "float", "example": 41.0108 },
          "lng": { "type": "number", "format": "float", "example": 28.9482 }
        }
      },
      "ForecastPoint": {
        "type": "object",
        "properties": {
          "uv": { "type": "number", "format": "float", "nullable": true, "example": 6.2 },
          "uv_time": { "type": "string", "format": "date-time", "nullable": true, "example": "2026-07-03T11:00:00+00:00" }
        }
      },
      "CurrentResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              { "$ref": "#/components/schemas/CityBase" },
              {
                "type": "object",
                "properties": {
                  "uv": { "type": "number", "format": "float", "nullable": true, "example": 6.2 },
                  "uv_time": { "type": "string", "format": "date-time", "nullable": true },
                  "uv_max": { "type": "number", "format": "float", "nullable": true, "example": 8.1 },
                  "uv_max_time": { "type": "string", "format": "date-time", "nullable": true },
                  "risk_level": { "type": "string", "nullable": true, "enum": ["Low", "Moderate", "High", "Very High", "Extreme", null], "example": "High" }
                }
              }
            ]
          }
        }
      },
      "ForecastResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              { "$ref": "#/components/schemas/CityBase" },
              {
                "type": "object",
                "properties": {
                  "forecast": { "type": "array", "items": { "$ref": "#/components/schemas/ForecastPoint" } }
                }
              }
            ]
          }
        }
      },
      "HistoryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "allOf": [
              { "$ref": "#/components/schemas/CityBase" },
              {
                "type": "object",
                "properties": {
                  "history": {
                    "type": "object",
                    "description": "Average UV index keyed by ISO date (one entry per month).",
                    "additionalProperties": { "type": "number", "format": "float" }
                  }
                }
              }
            ]
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "message": { "type": "string", "example": "Unauthenticated." }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API token.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "message": "Unauthenticated." } } }
      },
      "NotFound": {
        "description": "City not found.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "message": "Not found." } } }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (60 requests per minute).",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" }, "example": { "message": "Too Many Attempts." } } }
      }
    }
  }
}
