{"openapi":"3.1.0","info":{"title":"KaiCast Ocean Conditions API","version":"1.0.0","summary":"Free, keyless dive and snorkel conditions: visibility, swell, wind, tide, rating, confidence.","description":"Point lookups of ocean conditions for dive and snorkel spots: one spot and up to seven days per request.\nNo key required. Identify your client in `User-Agent`.\n\nFair use: generous per-caller limits apply, and asking about many DIFFERENT spots in a short window is throttled (429 with `Retry-After`). Repeat lookups of the same spot are never breadth-limited.\nCoverage grows by region; list it with `/api/v1/spots`.","contact":{"name":"KaiCast","url":"https://kaicast.com"},"termsOfService":"https://kaicast.com/terms"},"servers":[{"url":"https://kaicast.com"}],"paths":{"/api/v1/conditions":{"get":{"operationId":"getConditions","summary":"Conditions for one spot over a date range","description":"Returns the current nowcast (when today is in range) and 3-hour forecast periods with visibility, swell, wind, tide, a condition rating, confidence and a short plain-language reason. Identify the spot by `spot` id, or by `lat`+`lon` (snapped to the nearest covered spot within 30 km). Dates are the spot's local calendar dates; at most 7 days per request.","parameters":[{"name":"spot","in":"query","schema":{"type":"string","pattern":"^[a-z0-9-]{1,64}$"},"description":"Spot id from /api/v1/spots, e.g. `three-tables`."},{"name":"lat","in":"query","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"lon","in":"query","schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"First local date (default: today)."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Last local date, inclusive (default: from + 6)."}],"responses":{"200":{"description":"Conditions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Conditions"}}}},"400":{"description":"RFC 9457 problem details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"RFC 9457 problem details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"RFC 9457 problem details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate or breadth limit. Honor `Retry-After`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Data temporarily unavailable. Honor `Retry-After`.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/spots":{"get":{"operationId":"listSpots","summary":"Covered spots (metadata only, no conditions)","description":"Directory of covered spots with ids, names, regions and coordinates. Filter by region, by name, or sort by distance from a point.","parameters":[{"name":"region","in":"query","schema":{"type":"string"},"description":"Region slug, e.g. `us-hi-oahu`."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Case-insensitive name/id substring."},{"name":"lat","in":"query","schema":{"type":"number"}},{"name":"lon","in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"Spots and regions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpotList"}}}},"400":{"description":"RFC 9457 problem details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"RFC 9457 problem details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/recommendations":{"get":{"operationId":"recommendSpot","summary":"Ranked spot picks for an activity, area and day (decision).","description":"Top 3 (max 5) spots in one area for one spot-local day, each with its best daylight window, why, confidence, caveats and a KaiCast spot card. Uncovered places return `status: not_covered` (200), not an error. Free during early access; an API key is optional and will be required when metering starts.","tags":["Decisions"],"security":[{},{"kaicastBearer":[]},{"kaicastKey":[]}],"parameters":[{"name":"region","in":"query","schema":{"type":"string"},"description":"Region id from /api/v1/coverage, e.g. `us-hi-oahu`. Pass exactly one of region, spot, or lat+lon."},{"name":"spot","in":"query","schema":{"type":"string"},"description":"Spot id."},{"name":"lat","in":"query","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"lon","in":"query","schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"radius_km","in":"query","schema":{"type":"number","default":40,"maximum":100},"description":"Search radius around lat/lon."},{"name":"activity","in":"query","required":true,"schema":{"type":"string","enum":["snorkel","dive","freedive","spearfish","surf"]}},{"name":"date","in":"query","schema":{"type":"string","format":"date"},"description":"Spot-local day, today … today+6. Default: today, or tomorrow once today's daylight windows have passed (see `date_rolled_forward`)."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":5,"default":3}}],"responses":{"200":{"description":"Recommendation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Recommendation"}}}},"400":{"description":"Bad parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Invalid or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Free allotment used up (when metering is on).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown spot.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Date outside the forecast horizon.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/best-day":{"get":{"operationId":"bestDay","summary":"The best day in a window for an activity at a destination (decision).","description":"Which spot-local day in a window of up to 7 days is best, why (versus the runner-up), every day's best score, and a KaiCast spot card for the winner. Destination: a spot, a region, or lat+lon with a radius.","tags":["Decisions"],"security":[{},{"kaicastBearer":[]},{"kaicastKey":[]}],"parameters":[{"name":"region","in":"query","schema":{"type":"string"},"description":"Region id from /api/v1/coverage, e.g. `us-hi-oahu`. Pass exactly one of region, spot, or lat+lon."},{"name":"spot","in":"query","schema":{"type":"string"},"description":"Spot id."},{"name":"lat","in":"query","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"lon","in":"query","schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"radius_km","in":"query","schema":{"type":"number","default":40,"maximum":100},"description":"Search radius around lat/lon."},{"name":"activity","in":"query","required":true,"schema":{"type":"string","enum":["snorkel","dive","freedive","spearfish","surf"]}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Default today."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive; at most 7 days. Default from+6."}],"responses":{"200":{"description":"Best day.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BestDay"}}}},"400":{"description":"Bad parameters.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Invalid or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"402":{"description":"Free allotment used up (when metering is on).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown spot.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Window outside the forecast horizon.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Temporarily unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/coverage":{"get":{"operationId":"listCoverage","summary":"Covered regions, spots, decision support and activities (fact).","tags":["Facts"],"parameters":[{"name":"region","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Coverage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Coverage"}}}}}}}},"components":{"schemas":{"Source":{"type":"object","description":"Attribution. Cite this when you surface KaiCast data: name and url at minimum.","required":["name","url","docs","citation"],"properties":{"name":{"type":"string","const":"KaiCast"},"url":{"type":"string","format":"uri","const":"https://kaicast.com"},"docs":{"type":"string","format":"uri","const":"https://kaicast.com/developers"},"citation":{"type":"string","description":"Ready-to-use one-line citation."}}},"Region":{"type":"object","required":["id","name","country","admin1"],"properties":{"id":{"type":"string","example":"us-hi-oahu","description":"Global region slug: {iso-country}-{admin1}-{area}."},"name":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2."},"admin1":{"type":"string"}}},"Period":{"type":"object","required":["kind","start","end","rating","score","visibility_ft","visibility_m","swell_height_ft","swell_height_m","swell_period_s","swell_from_deg","wind_speed_kt","wind_gust_kt","wind_from_deg","tide_state","tide_height_ft","water_temp_c","confidence","visibility_source","why"],"properties":{"kind":{"type":"string","enum":["nowcast","forecast"],"description":"`nowcast` is the current-hour estimate; `forecast` is a 3-hour block."},"start":{"type":["string","null"],"format":"date-time","description":"ISO 8601 with the spot's UTC offset."},"end":{"type":["string","null"],"format":"date-time"},"rating":{"type":["string","null"],"enum":["excellent","great","good","fair","no-go",null],"description":"Overall dive/snorkel condition tier, derived from `score`. Low visibility caps the rating no matter how calm the rest is."},"score":{"type":["integer","null"],"minimum":0,"maximum":100,"description":"Composite condition score; higher is better."},"visibility_ft":{"type":["integer","null"],"description":"Estimated underwater horizontal visibility, feet."},"visibility_m":{"type":["number","null"]},"swell_height_ft":{"type":["number","null"],"description":"Nearshore significant swell height at the spot (exposure-adjusted), feet."},"swell_height_m":{"type":["number","null"]},"swell_period_s":{"type":["number","null"]},"swell_from_deg":{"type":["number","null"],"description":"Direction swell arrives FROM, degrees true."},"wind_speed_kt":{"type":["number","null"]},"wind_gust_kt":{"type":["number","null"]},"wind_from_deg":{"type":["number","null"],"description":"Direction wind blows FROM, degrees true."},"tide_state":{"type":["string","null"],"description":"rising | falling | high | low."},"tide_height_ft":{"type":["number","null"],"description":"Feet above MLLW."},"water_temp_c":{"type":["number","null"]},"confidence":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Confidence in the visibility estimate (0–1)."},"visibility_source":{"type":["string","null"],"enum":["satellite","heuristic",null]},"why":{"type":["string","null"],"description":"One or two plain-language sentences explaining the rating."}}},"Conditions":{"type":"object","required":["schema","spot","query","range","generated_at","next_update_after","data_quality","tide_datum","now","periods","tide_events","sources","links","attribution","source","data_credits","disclaimer"],"properties":{"schema":{"type":"string","const":"kaicast.conditions.v1"},"spot":{"type":"object","required":["id","name","region","lat","lon","timezone"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"region":{"$ref":"#/components/schemas/Region"},"lat":{"type":"number"},"lon":{"type":"number"},"timezone":{"type":"string","description":"IANA zone."}}},"query":{"type":"object","description":"Echo of the request. `resolved_from` is set when lat/lon was snapped to the nearest spot.","properties":{"spot":{"type":["string","null"]},"lat":{"type":["number","null"]},"lon":{"type":["number","null"]},"from":{"type":["string","null"]},"to":{"type":["string","null"]},"resolved_from":{"type":["object","null"],"properties":{"lat":{"type":"number"},"lon":{"type":"number"},"distance_km":{"type":"number"}}}}},"range":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"available_from":{"type":["string","null"],"format":"date"},"available_to":{"type":["string","null"],"format":"date"}}},"generated_at":{"type":["string","null"],"format":"date-time"},"next_update_after":{"type":["string","null"],"format":"date-time","description":"Do not expect newer data before this."},"data_quality":{"type":"object","properties":{"visibility_source":{"type":["string","null"],"enum":["satellite","heuristic",null]},"freshness":{"type":["string","null"]}}},"tide_datum":{"type":"string","const":"MLLW"},"now":{"oneOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}],"description":"Present when today is in range."},"periods":{"type":"array","items":{"$ref":"#/components/schemas/Period"}},"tide_events":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["high","low"]},"time":{"type":"string","format":"date-time"},"height_ft":{"type":["number","null"]}}}},"sources":{"type":"array","items":{"type":"string"}},"links":{"type":"object","properties":{"page":{"type":"string","format":"uri"},"app":{"type":"string","format":"uri"},"docs":{"type":"string","format":"uri"}}},"attribution":{"type":"string","description":"Human-readable attribution sentence. `source` is the structured form."},"source":{"$ref":"#/components/schemas/Source"},"data_credits":{"type":"array","description":"Upstream data providers this response drew on. Several licences (OpenWeather CC BY-SA 4.0, Open-Meteo CC BY 4.0, Copernicus Marine) require showing `credit` with a link to `url` wherever the data is displayed.","items":{"type":"object","required":["provider","credit","url","license"],"properties":{"provider":{"type":"string"},"credit":{"type":"string"},"url":{"type":"string","format":"uri"},"license":{"type":"string"}}}},"disclaimer":{"type":"string","description":"Estimates, not official forecasts; not for navigation."}}},"Spot":{"type":"object","required":["id","name","region","lat","lon","timezone","links"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"region":{"$ref":"#/components/schemas/Region"},"lat":{"type":"number"},"lon":{"type":"number"},"timezone":{"type":["string","null"]},"distance_km":{"type":"number","description":"Present when lat/lon was given."},"links":{"type":"object","properties":{"conditions":{"type":"string","format":"uri"},"page":{"type":"string","format":"uri"}}}}},"SpotList":{"type":"object","required":["schema","regions","spots","source"],"properties":{"schema":{"type":"string","const":"kaicast.spots.v1"},"source":{"$ref":"#/components/schemas/Source"},"regions":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Region"},{"type":"object","properties":{"spot_count":{"type":"integer"}}}]}},"spots":{"type":"array","items":{"$ref":"#/components/schemas/Spot"}}}},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string","description":"Stable machine code, e.g. `unknown_spot`, `breadth_limit`."},"source":{"$ref":"#/components/schemas/Source"}}},"DecisionDataCredit":{"type":"object","required":["provider","credit","url","license"],"properties":{"provider":{"type":"string"},"credit":{"type":"string","description":"Attribution text the licence requires. Show it with the data."},"url":{"type":"string","format":"uri"},"license":{"type":"string"}}},"Caveat":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine code: visibility_estimated, stale_inputs, long_lead_time, marginal_conditions, location_snapped, proxy_activity_model, verify_fishing_rules, regulated_area, regulations_not_checked."},"message":{"type":"string","description":"Plain-language caveat. Relay it to the user."}}},"Confidence":{"type":"object","required":["value","label","factors"],"properties":{"value":{"type":"number","minimum":0,"maximum":1,"description":"Product of the factors."},"label":{"type":"string","enum":["high","medium","low"]},"factors":{"type":"object","required":["model","visibility_source","freshness","lead_time","activity_fit"],"properties":{"model":{"type":"number","description":"The facts layer's own visibility confidence for this period."},"visibility_source":{"type":"number","description":"1.0 satellite, 0.8 heuristic."},"freshness":{"type":"number","description":"Input freshness (live 1.0 … none 0.6)."},"lead_time":{"type":"number","description":"Decays 5% per day ahead, floor 0.6."},"activity_fit":{"type":"number","description":"1.0 native model, 0.85 proxy."}}}}},"BestWindow":{"type":"object","required":["start","end","start_local","end_local","score","rating"],"properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"start_local":{"type":"string","description":"HH:MM spot-local."},"end_local":{"type":"string"},"score":{"type":"integer","minimum":0,"maximum":100},"rating":{"type":["string","null"],"enum":["excellent","great","good","fair","no-go",null]}}},"DecisionMetrics":{"type":"object","required":["visibility_ft","swell_height_ft","swell_period_s","swell_from","wind_speed_kt","wind_from","water_temp_f","tide_state"],"properties":{"visibility_ft":{"type":["integer","null"]},"swell_height_ft":{"type":["number","null"]},"swell_period_s":{"type":["number","null"]},"swell_from":{"type":["string","null"],"description":"8-point compass direction the swell comes FROM."},"wind_speed_kt":{"type":["number","null"]},"wind_from":{"type":["string","null"]},"water_temp_f":{"type":["integer","null"]},"tide_state":{"type":["string","null"]}}},"SpotCard":{"type":"object","description":"Compact branded KaiCast card. Render it (or `card_markdown`) in chat, including the CTA link.","required":["version","spot_id","spot_name","region_name","date","date_label","activity","tier","tier_label","tier_color","score","headline","best_window","metrics","image_url","links","cta","attribution","credits_text"],"properties":{"version":{"type":"integer","const":1},"spot_id":{"type":"string"},"spot_name":{"type":"string"},"region_name":{"type":["string","null"]},"date":{"type":"string","format":"date"},"date_label":{"type":"string","description":"Today | Tomorrow | e.g. \"Sat, Oct 10\"."},"activity":{"type":["string","null"]},"tier":{"type":["string","null"],"enum":["excellent","great","good","fair","no-go",null]},"tier_label":{"type":"string"},"tier_color":{"type":"string","description":"Hex colour for the tier stripe/pill."},"score":{"type":["integer","null"]},"headline":{"type":["string","null"]},"best_window":{"oneOf":[{"type":"object","properties":{"start_local":{"type":"string"},"end_local":{"type":"string"}}},{"type":"null"}]},"metrics":{"type":"object","properties":{"visibility":{"type":["string","null"]},"swell":{"type":["string","null"]},"wind":{"type":["string","null"]},"water_temp":{"type":["string","null"]}}},"image_url":{"type":"string","format":"uri","description":"1200×630 share image (PNG)."},"links":{"type":"object","required":["share","app","forecast"],"properties":{"share":{"type":"string","format":"uri"},"app":{"type":"string","description":"kaicast:// deep link (opens the app when installed)."},"forecast":{"type":"string","format":"uri"}}},"cta":{"type":"object","required":["label","text","url"],"properties":{"label":{"type":"string"},"text":{"type":"string"},"url":{"type":"string","format":"uri"}}},"attribution":{"type":"string"},"credits_text":{"type":["string","null"],"description":"Upstream data credits as one line; render it with the card."}}},"Pick":{"type":"object","required":["rank","spot","distance_km","date","score","rating","best_window","why","metrics","confidence","caveats","data_credits","card"],"properties":{"rank":{"type":"integer","minimum":1},"spot":{"type":"object","required":["id","name","region","lat","lon"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"region":{"$ref":"#/components/schemas/Region"},"lat":{"type":"number"},"lon":{"type":"number"}}},"distance_km":{"type":["number","null"],"description":"From the query point (lat/lon queries only)."},"date":{"type":"string","format":"date"},"score":{"type":"integer","minimum":0,"maximum":100,"description":"Verbatim from /api/v1/conditions for this period."},"rating":{"type":["string","null"],"enum":["excellent","great","good","fair","no-go",null]},"best_window":{"$ref":"#/components/schemas/BestWindow"},"why":{"type":"object","required":["summary","factors","model_note"],"properties":{"summary":{"type":"string"},"factors":{"type":"array","items":{"type":"string"}},"model_note":{"type":["string","null"],"description":"The forecast model's own explanation for this period."},"versus_next":{"type":["string","null"],"description":"best_day only: margin over the runner-up."}}},"metrics":{"$ref":"#/components/schemas/DecisionMetrics"},"confidence":{"$ref":"#/components/schemas/Confidence"},"caveats":{"type":"array","items":{"$ref":"#/components/schemas/Caveat"}},"data_credits":{"type":"array","items":{"$ref":"#/components/schemas/DecisionDataCredit"},"description":"Upstream data credits for the data this answer republishes (from the facts layer). Required attribution: show them."},"card":{"$ref":"#/components/schemas/SpotCard"}}},"ActivityInfo":{"type":"object","required":["id","label","model","note"],"properties":{"id":{"type":"string","enum":["snorkel","dive","freedive","spearfish","surf"]},"label":{"type":"string"},"model":{"type":"string","enum":["native","proxy","unsupported"],"description":"native = scored for this activity; proxy = shared condition score with caveats; unsupported = not ranked."},"note":{"type":"string"}}},"DecisionStatus":{"type":"string","enum":["ok","no_data","not_covered","conditions_only","activity_not_modeled"],"description":"ok: picks present. no_data: covered but no daylight data. not_covered: outside KaiCast coverage (see coverage.nearest_covered). conditions_only: facts but no credible visibility model. activity_not_modeled: e.g. surf — use /api/v1/conditions."},"Recommendation":{"type":"object","required":["schema","query","activity","generated_at","disclaimer","pricing","data_credits","status","coverage","picks","cards","source"],"properties":{"schema":{"type":"string","const":"kaicast.recommendation.v1"},"source":{"$ref":"#/components/schemas/Source"},"query":{"type":"object"},"activity":{"$ref":"#/components/schemas/ActivityInfo"},"generated_at":{"type":"string","format":"date-time"},"disclaimer":{"type":"string"},"pricing":{"type":"object","properties":{"layer":{"type":"string","const":"decision"},"plan":{"type":"string"}}},"data_credits":{"type":"array","items":{"$ref":"#/components/schemas/DecisionDataCredit"},"description":"Upstream data credits for the data this answer republishes (from the facts layer). Required attribution: show them."},"status":{"$ref":"#/components/schemas/DecisionStatus"},"coverage":{"type":"object","properties":{"status":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"nearest_covered":{"type":"object"}}},"date":{"type":"string","format":"date"},"date_label":{"type":"string"},"date_rolled_forward":{"type":"boolean","description":"True when no `date` was given and today's daylight windows had passed, so the picks are for tomorrow (`message` says so)."},"considered":{"type":"object","description":"How many spots were scored, excluded (not suited) or skipped (data unavailable)."},"message":{"type":["string","null"]},"facts_hint":{"type":"object","description":"activity_not_modeled only: where to get the facts."},"picks":{"type":"array","maxItems":5,"items":{"$ref":"#/components/schemas/Pick"}},"cards":{"type":"array","items":{"$ref":"#/components/schemas/SpotCard"}},"card_markdown":{"type":"string","description":"The cards as Markdown, for text-only chat surfaces."}}},"BestDay":{"type":"object","required":["schema","query","activity","generated_at","disclaimer","pricing","data_credits","status","coverage","cards","source"],"properties":{"schema":{"type":"string","const":"kaicast.best_day.v1"},"source":{"$ref":"#/components/schemas/Source"},"query":{"type":"object"},"activity":{"$ref":"#/components/schemas/ActivityInfo"},"generated_at":{"type":"string","format":"date-time"},"disclaimer":{"type":"string"},"pricing":{"type":"object"},"data_credits":{"type":"array","items":{"$ref":"#/components/schemas/DecisionDataCredit"},"description":"Upstream data credits for the data this answer republishes (from the facts layer). Required attribution: show them."},"status":{"$ref":"#/components/schemas/DecisionStatus"},"coverage":{"type":"object"},"range":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"requested_from":{"type":"string"},"requested_to":{"type":"string"}}},"considered":{"type":"object"},"message":{"type":["string","null"]},"best":{"oneOf":[{"allOf":[{"$ref":"#/components/schemas/Pick"},{"type":"object","properties":{"date_label":{"type":"string"}}}]},{"type":"null"}]},"runner_up":{"oneOf":[{"type":"object","properties":{"date":{"type":"string"},"score":{"type":"integer"},"rating":{"type":["string","null"]},"spot":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}},{"type":"null"}]},"days":{"type":"array","items":{"type":"object","required":["date","date_label","score","rating","spot","best_window","summary"],"properties":{"date":{"type":"string","format":"date"},"date_label":{"type":"string"},"score":{"type":["integer","null"]},"rating":{"type":["string","null"]},"spot":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},{"type":"null"}]},"best_window":{"oneOf":[{"$ref":"#/components/schemas/BestWindow"},{"type":"null"}]},"summary":{"type":"string"}}}},"cards":{"type":"array","items":{"$ref":"#/components/schemas/SpotCard"}},"card_markdown":{"type":"string"}}},"Coverage":{"type":"object","required":["schema","generated_at","regions","activities","notes","source"],"properties":{"schema":{"type":"string","const":"kaicast.coverage.v1"},"source":{"$ref":"#/components/schemas/Source"},"generated_at":{"type":"string","format":"date-time"},"regions":{"type":"array","items":{"type":"object","required":["id","name","country","admin1","decision_support","spot_count","bbox","spots"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"country":{"type":["string","null"]},"admin1":{"type":["string","null"]},"decision_support":{"type":"string","enum":["full","conditions_only"]},"spot_count":{"type":"integer"},"bbox":{"type":"object","properties":{"south":{"type":"number"},"west":{"type":"number"},"north":{"type":"number"},"east":{"type":"number"}}},"spots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"lat":{"type":"number"},"lon":{"type":"number"}}}}}}},"activities":{"type":"array","items":{"$ref":"#/components/schemas/ActivityInfo"}},"notes":{"type":"array","items":{"type":"string"}}}}},"securitySchemes":{"kaicastBearer":{"type":"http","scheme":"bearer","description":"Optional during early access. `Authorization: Bearer kc_live_…`."},"kaicastKey":{"type":"apiKey","in":"header","name":"X-KaiCast-Key","description":"Alternative header for the same key."}}}}