SC1000 probe data API
Readings from a Hach SC1000 controller, logged once per second by PAGE Technologies. Raw values as the controller reports them: no calibration correction, filtering or QA/QC.
Keys
Every call except /v1/health needs an API key from PAGE Technologies. Send it as a header,
Authorization: Bearer KEY or X-API-Key: KEY, or where headers are awkward
(a browser, Excel, pandas) as ?key=KEY in the URL.
Calls
GET /v1/latest | The newest reading and its age in seconds. For live data, poll it: a new reading arrives every second. |
GET /v1/history | Readings over a time range; the last hour unless you say otherwise. |
GET /v1/days | The days on record, with each day's first and last reading. |
GET /v1/columns | What each column is: probe, type, unit, the days it was logged, and known issues. |
GET /v1/health | Whether the logger is writing (no key needed). |
Parameters
start, end | history: the range, start included, end not. Defaults: the hour before now. |
date | history: one whole local day, e.g. date=2026-11-09 (instead of start and end). |
every | history: one reading per this many seconds, the first of each interval:
every=60 is one a minute, every=3600 one an hour, every=86400 one a day
from local midnight. Default 1, every reading.
One call returns at most 100,000 readings: a day at every=1, or 69 days at every=60. |
columns | latest, history: column names, comma-separated; * matches anything, e.g.
columns=peff_*,ldo_do_ppm. Default: all. |
format | json (default) or csv. |
Times can be 2026-11-09T08:00 (site time, America/Denver), 2026-11-09T15:00:00Z or any other UTC offset,
a date 2026-11-09 (its midnight), Unix seconds, now, or relative: -90s,
-30m, -6h, -7d. Times come back in RFC 3339 with the UTC offset in effect at the site,
e.g. 2026-11-09T08:00:00-07:00. A missing value is null in JSON, empty in CSV.
Examples
KEY=your-key curl -H "Authorization: Bearer $KEY" https://raspberrypi.tailee6df.ts.net/v1/latest curl -H "Authorization: Bearer $KEY" "https://raspberrypi.tailee6df.ts.net/v1/history?start=-6h&every=60&columns=peff_*" curl -H "Authorization: Bearer $KEY" "https://raspberrypi.tailee6df.ts.net/v1/history?date=2026-11-09&format=csv" -o 2026-11-09.csv
import requests
r = requests.get("https://raspberrypi.tailee6df.ts.net/v1/history",
params={"start": "-1d", "every": 300, "columns": "cas_nh4,peff_nh4"},
headers={"Authorization": f"Bearer {KEY}"})
rows = r.json()["rows"] # [{"time": "...", "cas_nh4": 2.6, "peff_nh4": 28.9}, ...]
import pandas as pd
df = pd.read_csv("https://raspberrypi.tailee6df.ts.net/v1/history?date=2026-11-09&every=60&format=csv&key=" + KEY,
parse_dates=["time"])
Reading the data
- Probes:
ldo_*CAS LDO (dissolved oxygen, mg/L),cas_*CAS ANISE,peff_*PEFF ANISE./v1/columnsdescribes each column. - If the controller stops answering, the last value is repeated for up to 10 s, then left blank. A second with no reading at all means the logger was not running.
*_heartbeatrises about once a second while the controller updates that probe. If it stops, the values are stale.- PEFF ANISE is logged from 2026-10-21 12:01 MDT. From 11:49 to 12:01 MDT that day the controller was being reconfigured, and CAS ANISE values in that window are returned blank.