Skip to main content

Documentation Index

Fetch the complete documentation index at: https://dev.1st.app/llms.txt

Use this file to discover all available pages before exploring further.

The /readings endpoint is for interactive use — last 24h, single sensor. For bulk pulls across many sensors and long time ranges, use GET /v1/readings.csv instead. One request, one rate-limit hit, returns a streamed CSV body you save to disk.

Curl

curl "https://api.1st.app/v1/readings.csv?from=2026-02-01T00:00:00Z&to=2026-05-01T00:00:00Z" \
  -H "Authorization: Bearer $ST_API_KEY" \
  -o readings.csv
Default shape=long returns one row per (sensor, bucket). Columns: bucket_at, sensor_id, display_name, co2_ppm, temp_c, humidity_pct, lux, spl_db, valid_mask.

Spreadsheet-friendly wide shape

Add ?shape=wide to get one row per bucket with one column per (sensor × metric) — the layout spreadsheets actually want:
curl "https://api.1st.app/v1/readings.csv?from=2026-02-01T00:00:00Z&to=2026-05-01T00:00:00Z&shape=wide" \
  -H "Authorization: Bearer $ST_API_KEY" \
  -o readings-wide.csv
The header row looks like bucket_at, room4.co2_ppm, room4.temp_c, room12.co2_ppm, .... Column names are derived from each sensor’s display_name (lowercased, non-alphanumeric replaced with _, collision suffixes when needed).

Sensors filter

To restrict the export to a subset, pass ?sensors= with a comma- separated list of UUIDs:
curl "https://api.1st.app/v1/readings.csv?from=2026-02-01T00:00:00Z&to=2026-05-01T00:00:00Z&sensors=aaaa...,bbbb..." \
  -H "Authorization: Bearer $ST_API_KEY" \
  -o subset.csv
Omit sensors to include every non-archived sensor in the team.

Sheets / Excel direct

Both connectors can fetch the CSV directly if you pass the key as a query parameter (they can’t set headers):
=IMPORTDATA("https://api.1st.app/v1/readings.csv?from=2026-05-01T00:00:00Z&to=2026-05-08T00:00:00Z&shape=wide&key=1st_sk_...")
URLs containing ?key=... end up in upstream platform logs. Mint a dedicated read-only key per feed so rotation has small blast radius. Rotate any key whose URL has been shared.

Limits

  • Max range: 90 days per request.
  • Max rows: 250,000 per request. Wider requests get 413 — narrow the range or sensor list and re-call.
  • Floats are rounded to 2 decimals.
  • Timestamps are ISO 8601 UTC (Excel-parseable).

Python

import requests

resp = requests.get(
    f"{API_BASE}/v1/readings.csv",
    params={
        "from": "2026-02-01T00:00:00Z",
        "to": "2026-05-01T00:00:00Z",
        "shape": "wide",
    },
    headers={"Authorization": f"Bearer {API_KEY}"},
    stream=True,
)
resp.raise_for_status()
with open("readings.csv", "wb") as f:
    for chunk in resp.iter_content(chunk_size=8192):
        f.write(chunk)

Nightly job pattern

For unattended nightly pulls, use a read-scope key with a meaningful name (“Nightly BigQuery sync”) and call the CSV endpoint once. If the response exceeds 250k rows, split the range — e.g. 30 days per call, 12 calls per year of history.