Push your own satellite telemetry

Your spacecraft, in the same control room as the open-data fleet — isolated, and visible only to your organization.

Overwatch stores your telemetry as plain time series: a satellite name, a timestamp, a field name, a value. There is no schema to agree with us in advance and no format to convert to. If your ground segment can make an HTTPS request, it can push here.

1 · Get a token

Sign in, create your organization, then mint a service token from your account page. The page shows a ready-to-paste curl with your real token already in it.

Go to your account

The token identifies your organization and nothing else — it carries no personal identity, so it belongs in your ground segment's configuration. Revoke it from the same page if it leaks; the row survives so the audit trail does.

2 · Push a point

curl -i -X POST https://overwatch.confinia.io/api/v1/tenants/<your-token>/telemetry \
  -H 'content-type: application/json' \
  -d '{"satellite":"MYSAT-1",
       "points":[{"ts":"2026-08-21T11:20:00Z","field":"battery_v","value":7.42}]}'

A push that worked answers 202 with {"accepted":1,"satellite":"MYSAT-1"}. Use -i: without the status line a rejection can look exactly like a success.

The payload

FieldMeaning
satelliteFree-form name. It groups the series and is what you will click on in the app — pick the name your team already uses.
points[].tsISO 8601 timestamp, UTC. Backfill is fine: send historical points and they land in the right place on the chart.
points[].fieldFree-form field name. See the naming note below — it decides how much of the dashboard fills in by itself.
points[].valueA number, or a string for states and modes ("NOMINAL", "SAFE"). Numbers are charted; strings are kept and shown as-is.

Re-sending the same (satellite, ts, field) overwrites that point rather than duplicating it, so a retry after a network failure is always safe.

3 · Name fields so the dashboards fill themselves

Field names are yours to choose, but three are canonical and drive the fleet-wide panels:

battery_v     battery voltage   (volts)
battery_i     battery current   (amps, negative = discharging)
battery_pct   state of charge   (percent)

Use those names and your satellite gets the same battery panels as every other satellite in the control room, with no configuration. Anything else — temp_obc_c, rssi_dbm, mode — is stored and charted next to them. Naming a voltage vbatt is not wrong; it just means one panel stays empty that could have filled itself.

4 · Read it back

GET /api/v1/tenants/<your-token>/satellites          → what you have pushed
GET /api/v1/tenants/<your-token>/telemetry?satellite=MYSAT-1&field=battery_v&hours=24

Signed in as a member of the organization, the same data is at /api/v1/org/telemetry without a token, and in your organization's private Grafana.

5 · Limits

LimitValueWhat you get if you exceed it
Points per request1000413 — batch your pushes
Points per day, per organization200000429 — write to us and we raise it

These are the numbers the API actually enforces. A pass with a 30-second beacon and twenty fields is roughly 57,600 points a day, so the default suits a small fleet comfortably.

Errors worth recognising

CodeMeaningFix
401Unknown or revoked tokenMint a new one on the account page
403Your plan's satellite limitThe DevSat tier includes one satellite; upgrade for a fleet
413More than 1000 points in one requestSplit the batch
429Daily quota reachedWait for the period, or ask us to raise it

6 · Test before any hardware talks to us

Your satellite may not be flying yet — or may be a flatsat on a bench. The repository ships a simulator that speaks this exact API, so you can watch the whole path work first:

podman build -t simsat orbit-poc/simsat
podman run --rm --network=host \
  -e SIM_KEY=<your-token> \
  -e SIM_BASE=https://overwatch.confinia.io \
  -e SIM_SCENARIO=battery-decline simsat

It generates plausible housekeeping — battery and panels following the sunlit/eclipse cycle, temperatures lagging with thermal inertia, uptime counters, occasional dropped frames — and can inject faults on request. The satellite name is forced to a SIM prefix so simulated data is never mistaken for real.

Everything here works the same on a self-hosted install, against your own hostname. The API is identical; only the base URL changes.

Your data

Private telemetry is isolated per organization by PostgreSQL row-level security — the database enforces it, not the application. It is hosted in Europe, and it is yours: we delete it on request.