Open data
Shorelife publishes its daily water-quality forecast and lab history for 850 California beaches as static JSON files. They are free to use under the terms on this page. No key is needed.
Files
https://shorelifeca.org/data/api/beaches.json- All 850 stations. Each row has the station's name, county, coordinates, advisory links and a
forecastobject for today, ornullwhen the station has no recent lab test. https://shorelifeca.org/data/api/parent_beaches.json- Beaches grouped by location, with the worst band of their stations.
https://shorelifeca.org/data/api/beach/{beach_id}.json- One file per station: the last 52 lab tests (
observations), the forecast explanation (explain), the hourly outlook (hourly) and tides (tides). Sections arenullwhen not available. https://shorelifeca.org/data/api/health.json- Pipeline freshness and model status.
Files update once a day after the morning pipeline run, usually before 10 AM Pacific. Every file is served with Access-Control-Allow-Origin: *, so a browser can fetch it directly. Cache for at least ten minutes. Use forecast_generated_at and is_stale to show the age of a forecast.
Fields
beach_id- Stable key, same as in the file name.
forecast_date- Date of the forecast.
risk_band- Low, Moderate, High, Very High.
p_exceed- Probability that the next lab test exceeds the state limit: 104 MPN/100 mL for culture tests, 1413 copies/100 mL for San Diego ddPCR tests.
p_exceed_lower/p_exceed_upper- Prediction interval.
official_advisory_active+advisory_website- County posting; always show the county link when the flag is true.
sample_age_days- Days since the latest lab sample.
is_stale- True when the forecast has not updated recently.
model_version- Model version identifier.
top_drivers- Short plain-text reasons.
sample_time- Timestamp of the lab sample.
value+units+method- Result value, measurement units, and test method.
exceeds_stv- True when the sample exceeds the single-sample water quality threshold.
Example
const res = await fetch("https://shorelifeca.org/data/api/beaches.json");
const beaches = await res.json();
const today = beaches.filter((b) => b.forecast !== null);
console.log(today[0].name, today[0].forecast.risk_band, today[0].forecast.p_exceed);curl -s https://shorelifeca.org/data/api/health.jsonTerms of use
- Attribution is required. Show the text “Forecast by Shorelife” with a link to https://shorelifeca.org wherever the data appears: web page, app screen, print, or another API.
- Do not present the data as official county or state results, and do not imply that a county, the State Water Board or Shorelife endorses your product.
- The forecast is an estimate. It does not replace an official advisory. When
official_advisory_activeis true, show the county's advisory link next to the forecast. - Do not remove the
is_stale,forecast_generated_atorsample_age_daysinformation when you show a forecast. - Fetch each file at most once every ten minutes. For higher volumes, a different format, or commercial use, email ceo@shorelifeca.org first.
- The data files are licensed under Creative Commons Attribution 4.0 (CC BY 4.0). The pipeline code is open source under AGPL-3.0 at https://github.com/kylechoi101/surf-health.
Coverage and limits
Stations get a forecast when they have a lab test from the last 30 days. Counties test most beaches about once a week, and some county feeds pause for weeks. Read the data sources page for the current state of each county.
Field names may change. This page records changes to the files. Last change: 2026-10-16 (first version of this page).
Questions
Technical questions: support@shorelifeca.org. Partnerships and commercial use: ceo@shorelifeca.org.