API & submitters

GridWitness isn't tied to Home Assistant. Anyone with grid or weather measurements can submit them against the published, versioned schema.

Concepts

Node

One measurement point or stream. Register one node per site — it has a random node_id and a bearer token.

Channels

The named quantities you send (see the schema). Electrical and weather.

Consent set

The channels a node may send, chosen at registration. The server rejects any row outside the set — you cannot accidentally over-submit.

Producer

A string naming your software, e.g. acme-energy-app/2.3, recorded for attribution and support.

1 · Get a key

The easiest way is to create an account and issue a key from your dashboard — pick the channels and location tier, and the token is shown once. A key issued this way is tied to your account, so you can manage or erase it later.

2 · Send batches

POST /v1/samples with your Bearer token. Timestamps are UTC ISO-8601 with a Z; electrical rows use ts_utc, weather rows use time. One row per phase where applicable (single phase is 1p).

send.shPOST /v1/samples
curl -X POST https://ingest.twinscrollgridbalancer.co.uk/v1/samples \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{
    "node_id": "'"$NODE_ID"'",
    "client_send_ts": "2026-07-16T14:32:35.010Z",
    "schema_version": "1.0",
    "electrical": [
      {"ts_utc": "2026-07-16T14:32:05.250Z", "ts_source": "device", "phase": "1p", "frequency_hz": 49.998, "voltage_v": 241.2}
    ]
  }'

The response echoes server_receive_ts (pair it with your send time for an NTP-style transport offset), plus accepted, duplicates, and any rejected rows with reasons.

3 · Handle the responses

Deduplication — rows are idempotent on (node_id, ts_utc, phase). Re-sending is safe; it counts as a duplicate, not an error. This makes retries and backfill safe.
Backpressure503 with Retry-After means busy; buffer and retry later.
Rate limit429 means too fast for this node; back off.
Validation400 returns a per-row rejected list telling you exactly what was wrong.

Submitting on behalf of other people?

Honour the same deal the Home Assistant integration makes: only register the channels the person agreed to share (current and power are never a default), never put personal data in rows, and support withdrawal. Historical backfill is welcome — rows keep their original timestamps and gaps stay visible rather than being papered over.