{"openapi":"3.1.0","info":{"title":"Mashong Weather API","version":"1.1.0","description":"Reusable WeatherKit API. All weather responses must display Apple Weather attribution. Browser/native clients use short-lived session tokens; service keys remain on servers. Raw ratios 0..1; summary percentages 0..100. No permanent weather archive."},"servers":[{"url":"https://weather.mashong.com"},{"url":"https://mashong-weather.kingteer2.workers.dev"}],"paths":{"/v1/weather":{"get":{"operationId":"getWeather","summary":"Current, hourly and daily together","security":[{"serviceBearer":[]},{"sessionBearer":[]}],"parameters":[{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"language","in":"query","required":false,"schema":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Z]{2}$","description":"ISO Alpha-2. Required for alerts."}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10,"default":7}}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeatherResponse"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/weather/current":{"get":{"operationId":"getCurrent","summary":"Current conditions","security":[{"serviceBearer":[]},{"sessionBearer":[]}],"parameters":[{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"language","in":"query","required":false,"schema":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Z]{2}$","description":"ISO Alpha-2. Required for alerts."}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10,"default":7}}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeatherResponse"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/weather/hourly":{"get":{"operationId":"getHourly","summary":"Hourly forecast","security":[{"serviceBearer":[]},{"sessionBearer":[]}],"parameters":[{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"language","in":"query","required":false,"schema":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Z]{2}$","description":"ISO Alpha-2. Required for alerts."}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10,"default":7}}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeatherResponse"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/weather/daily":{"get":{"operationId":"getDaily","summary":"Daily forecast","security":[{"serviceBearer":[]},{"sessionBearer":[]}],"parameters":[{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"language","in":"query","required":false,"schema":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."}},{"name":"countryCode","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Z]{2}$","description":"ISO Alpha-2. Required for alerts."}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10,"default":7}}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeatherResponse"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/weather/alerts":{"get":{"operationId":"getAlerts","summary":"Unmodified supported weather alerts","security":[{"serviceBearer":[]},{"sessionBearer":[]}],"parameters":[{"name":"latitude","in":"query","required":true,"schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"longitude","in":"query","required":true,"schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"language","in":"query","required":false,"schema":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."}},{"name":"countryCode","in":"query","required":true,"schema":{"type":"string","pattern":"^[A-Z]{2}$","description":"ISO Alpha-2. Required for alerts."}},{"name":"hours","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":48,"default":24}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":10,"default":7}}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeatherResponse"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tokens":{"post":{"operationId":"createSessionToken","summary":"Trusted server issues a 5-minute user weather token","description":"Server credential only; authenticate and rate-limit the end user in your backend before calling. Session token cannot create another token. No browser-origin requests. Token is not an Apple JWT.","security":[{"serviceBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionToken"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Body exceeds 2048 bytes","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"JSON required","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"operationId":"health","summary":"Public liveness, no Apple probe","security":[],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/ready":{"get":{"operationId":"readiness","summary":"Authenticated config and signing readiness, no Apple network probe","security":[{"serviceBearer":[]}],"responses":{"200":{"description":"Success","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ready"}}}},"400":{"description":"Invalid input","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid or expired bearer token","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Origin or credential type forbidden","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited; Retry-After seconds","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."},"Retry-After":{"schema":{"type":"integer"},"description":"Seconds before retry. No automatic retry recommended."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Apple failed or data invalid/expired","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Disabled, unconfigured or unavailable","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Apple timed out","headers":{"X-Request-Id":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"},"description":"no-store for weather, tokens, errors."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"serviceBearer":{"type":"http","scheme":"bearer","description":"Long-lived per-service credential. Server only."},"sessionBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"5-minute Mashong weather token from your authenticated backend."}},"schemas":{"CurrentSummary":{"type":"object","properties":{"conditionCode":{"type":["string","null"]},"conditionText":{"type":"string"},"icon":{"type":"string","description":"Portable icon name, not an Apple Weather attribution mark."},"asOf":{"type":["string","null"],"format":"date-time"},"temperatureC":{"type":["number","null"]},"feelsLikeC":{"type":["number","null"]},"humidityPercent":{"type":["number","null"]},"windKph":{"type":["number","null"]},"precipitationIntensityMmPerHour":{"type":["number","null"]},"daylight":{"type":["boolean","null"]}},"required":["conditionCode","conditionText","icon","asOf","temperatureC","feelsLikeC","humidityPercent","windKph","precipitationIntensityMmPerHour","daylight"]},"HourSummary":{"type":"object","properties":{"conditionCode":{"type":["string","null"]},"conditionText":{"type":"string"},"icon":{"type":"string","description":"Portable icon name, not an Apple Weather attribution mark."},"forecastStart":{"type":["string","null"],"format":"date-time"},"temperatureC":{"type":["number","null"]},"feelsLikeC":{"type":["number","null"]},"precipitationProbabilityPercent":{"type":["number","null"]},"precipitationMm":{"type":["number","null"]},"humidityPercent":{"type":["number","null"]},"windKph":{"type":["number","null"]}},"required":["conditionCode","conditionText","icon","forecastStart","temperatureC","feelsLikeC","precipitationProbabilityPercent","precipitationMm","humidityPercent","windKph"]},"DaySummary":{"type":"object","properties":{"conditionCode":{"type":["string","null"]},"conditionText":{"type":"string"},"icon":{"type":"string","description":"Portable icon name, not an Apple Weather attribution mark."},"date":{"type":["string","null"],"format":"date"},"forecastStart":{"type":["string","null"],"format":"date-time"},"forecastEnd":{"type":["string","null"],"format":"date-time"},"minC":{"type":["number","null"]},"maxC":{"type":["number","null"]},"precipitationProbabilityPercent":{"type":["number","null"]},"precipitationMm":{"type":["number","null"]}},"required":["conditionCode","conditionText","icon","date","forecastStart","forecastEnd","minC","maxC","precipitationProbabilityPercent","precipitationMm"]},"Attribution":{"type":"object","properties":{"serviceName":{"type":"string"},"logoLight":{"type":"string","format":"uri"},"logoDark":{"type":"string","format":"uri"},"legalURLs":{"type":"array","minItems":1,"items":{"type":"string","format":"uri"}}},"required":["serviceName","logoLight","logoDark","legalURLs"]},"Error":{"type":"object","properties":{"error":{"type":"string"},"requestId":{"type":"string"}},"required":["error"]},"TokenRequest":{"type":"object","properties":{"subject":{"type":"string","pattern":"^[a-zA-Z0-9_-]{8,128}$","description":"Stable opaque authenticated user ID. Never email, phone or location. Supplied by your trusted backend."},"origin":{"type":["string","null"],"description":"Browser: exact HTTPS origin in ALLOWED_ORIGINS. Native: omit."}},"required":["subject"],"additionalProperties":false},"SessionToken":{"type":"object","properties":{"accessToken":{"type":"string"},"tokenType":{"const":"Bearer"},"expiresIn":{"const":300},"expiresAt":{"type":"string","format":"date-time"}},"required":["accessToken","tokenType","expiresIn","expiresAt"]},"Health":{"type":"object","properties":{"service":{"const":"mashong-weather"},"status":{"const":"ok"},"apiVersion":{"const":"1.1"}},"required":["service","status","apiVersion"]},"Ready":{"type":"object","properties":{"service":{"const":"mashong-weather"},"status":{"const":"ready"},"apiVersion":{"const":"1.1"},"upstream":{"const":"not_probed"}},"required":["service","status","apiVersion","upstream"]},"WeatherResponse":{"type":"object","properties":{"apiVersion":{"const":"1.1"},"provider":{"const":"Apple Weather"},"location":{"type":"object","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"language":{"type":"string","enum":["ko","ko-KR","en","en-US"],"default":"ko"},"timezone":{"type":"string","maxLength":64,"default":"Asia/Seoul","description":"Valid IANA timezone; explicitly set for users outside Korea."},"countryCode":{"type":["string","null"]},"hours":{"type":"integer","minimum":1,"maximum":48,"default":24},"days":{"type":"integer","minimum":1,"maximum":10,"default":7}},"required":["latitude","longitude","language","timezone","countryCode","hours","days"]},"fetchedAt":{"type":"string","format":"date-time","description":"Upstream retrieval completed at (may be cached)."},"retrievedAt":{"type":"string","format":"date-time","description":"Time this client request was served."},"cacheHit":{"type":"boolean"},"units":{"type":"object","additionalProperties":{"type":"string"}},"attribution":{"$ref":"#/components/schemas/Attribution"},"data":{"type":"object","description":"Requested Apple datasets with original metadata and values. hours/days arrays are trimmed to requested count. Alert collection is unchanged."},"summary":{"type":"object","properties":{"current":{"anyOf":[{"$ref":"#/components/schemas/CurrentSummary"},{"type":"null"}]},"hourly":{"type":"array","maxItems":48,"items":{"$ref":"#/components/schemas/HourSummary"}},"daily":{"type":"array","maxItems":10,"items":{"$ref":"#/components/schemas/DaySummary"}}},"required":["current","hourly","daily"]},"alertsSupported":{"type":"boolean","description":"Present on alerts endpoint. false means unsupported, not no alerts."}},"required":["apiVersion","provider","location","fetchedAt","retrievedAt","cacheHit","units","attribution","data","summary"]}}}}