Skip to the main content
Developers

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 forecast object for today, or null when 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 are null when 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.json

Terms of use

  1. 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.
  2. 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.
  3. The forecast is an estimate. It does not replace an official advisory. When official_advisory_active is true, show the county's advisory link next to the forecast.
  4. Do not remove the is_stale, forecast_generated_at or sample_age_days information when you show a forecast.
  5. Fetch each file at most once every ten minutes. For higher volumes, a different format, or commercial use, email ceo@shorelifeca.org first.
  6. 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.