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 device. For bulk pulls across many devices 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.

Picking a time range

The simplest way is ?last=, no timestamps to compute:
WantPass
Last 24 hours?last=24h
Last 7 days?last=7d
Last 30 days?last=30d
Last 90 days (the cap)?last=90d
For a specific calendar range, set from and to (ISO 8601 UTC):
?from=2026-02-01T00:00:00Z&to=2026-05-01T00:00:00Z
Or set just from and to defaults to “now”. With nothing set, you get the last 24 hours by default.

Example

curl "https://api.1st.app/v1/readings.csv?last=30d" \
  -H "Authorization: Bearer $ST_API_KEY" \
  -o readings.csv
Default shape=long returns one row per (device, bucket). Columns: bucket_at, device_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 (device × metric), the layout spreadsheets actually want:
curl "https://api.1st.app/v1/readings.csv?last=30d&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 device’s display_name (lowercased, non-alphanumeric replaced with _, collision suffixes when needed).

Devices filter

To restrict the export to a subset, pass ?devices= with a comma- separated list of UUIDs:
curl "https://api.1st.app/v1/readings.csv?last=30d&devices=aaaa...,bbbb..." \
  -H "Authorization: Bearer $ST_API_KEY" \
  -o subset.csv
Omit devices to include every device 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?last=7d&shape=wide&key=1st_sk_...")
URLs containing ?key=... end up in upstream platform logs. Create 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 device 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.