orbimon

API

Monitors

Read Starlink telemetry at raw, hourly, daily, and year resolution.

A monitor is one Starlink site in your organization. While the dish is connected, Orbimon stores roughly one sample per second, then serves coarser resolutions for longer ranges.

Discover monitors with Organizations → List monitors. Use a monitor API token (read access) for the endpoints below.

← API overview


What’s in a monitor

Monitor
├── Metadata (id, name, starlink_id, status)  → organization list
└── Metrics
      ├── raw      (~1 s)     short windows
      ├── hourly   (1 h)      days–weeks
      ├── daily    (1 d)      months
      └── year     (1 d)      up to 365 days
EndpointResolutionRecommended end − start
Raw~1 secondUp to 12 hours
Hourly1 hourUp to ~30 days
Daily1 dayWeeks to months
Year1 dayUp to 365 days

If the range is too wide for that endpoint, you get 400 invalid_request — switch to a coarser resolution.


Common query parameters

All metrics routes:

ParamRequiredDescription
startyesStart time (ISO 8601), inclusive — e.g. 2026-10-06T00:00:00Z
endyesEnd time (ISO 8601), inclusive

hourly, daily, and year also accept:

ParamDefaultDescription
metricavgAggregate to plot: avg | max | min | p95

p95 is most meaningful for latency; other fields follow avg/max/min as documented per backend.


Metric fields

Same field names across resolutions. Units are fixed.

FieldTypeUnit / notes
timestampstringSample or bucket time (ISO 8601)
connected0 | 1Link up in this sample/bucket
statestringe.g. CONNECTED, SEARCHING, DISCONNECTED
downlink_throughput_bpsnumberDownload, bits per second
uplink_throughput_bpsnumberUpload, bits per second
pop_ping_latency_msnumberLatency to Starlink POP (milliseconds)
pop_ping_drop_ratenumberPacket loss ratio 0–1 (not percent)

Obstructions

FieldTypeNotes
obstruction_percentnumberObstruction percentage from the dish
currently_obstructed0 | 1Obstructed at sample / in bucket
obstruction_durationnumberDuration metric from the dish
obstruction_intervalnumberInterval metric from the dish

Orientation & GPS

FieldTypeNotes
direction_azimuthnumber | nullDegrees
direction_elevationnumber | nullDegrees
tilt_angle_degnumber | nullDegrees
gps_satsnumber | nullGPS satellite count

Power & alerts

FieldTypeNotes
power_wattsnumber | nullPower draw when available
alertsstring[]Dish alert codes in this sample/bucket

Throughput is always bps (divide by 1_000_000 for Mbps in your client).


Get raw metrics

Per-second points for a short window.

GET /v1/monitors/:monitor_id/metrics/raw?start=2026-10-06T10:00:00Z&end=2026-10-06T12:00:00Z
Authorization: Bearer <monitor_token>

Constraints

  • end − start must be less than 12 hours
  • Limited by your plan’s raw retention

Response 200

{
  "data": [
    {
      "timestamp": "2026-10-06T10:00:01.000Z",
      "connected": 1,
      "state": "CONNECTED",
      "downlink_throughput_bps": 152000000,
      "uplink_throughput_bps": 21000000,
      "pop_ping_latency_ms": 38.2,
      "pop_ping_drop_rate": 0.002,
      "obstruction_percent": 1.4,
      "currently_obstructed": 0,
      "obstruction_duration": 0,
      "obstruction_interval": 0,
      "direction_azimuth": 182.1,
      "direction_elevation": 42.0,
      "tilt_angle_deg": 1.2,
      "gps_sats": 12,
      "power_watts": 78.5,
      "alerts": []
    }
  ],
  "meta": {
    "monitor_id": "mon_1736...",
    "resolution": "raw",
    "start": "2026-10-06T10:00:00.000Z",
    "end": "2026-10-06T12:00:00.000Z",
    "count": 7200
  }
}

Get hourly metrics

One point per hour. Empty hours may appear as disconnected / zero-filled buckets.

GET /v1/monitors/:monitor_id/metrics/hourly?start=2026-09-01T00:00:00Z&end=2026-09-07T23:59:59Z&metric=avg
Authorization: Bearer <monitor_token>

Constraints

  • Best for ranges from about 1 day up to 30 days
  • metric: avg | max | min | p95

Response 200

Same series shape as raw (data + meta), for example:

"meta": {
  "monitor_id": "mon_1736...",
  "resolution": "hourly",
  "metric": "avg",
  "start": "2026-09-01T00:00:00.000Z",
  "end": "2026-09-07T23:59:59.000Z",
  "count": 168
}

Get daily metrics

One point per calendar day.

GET /v1/monitors/:monitor_id/metrics/daily?start=2026-01-01&end=2026-03-31&metric=avg
Authorization: Bearer <monitor_token>

Constraints

  • Use for multi-week and multi-month ranges
  • start / end may be a date (YYYY-MM-DD) or a full ISO datetime
  • metric: avg | max | min | p95

Response 200

"meta": {
  "resolution": "daily",
  "metric": "avg",
  "count": 90
}

Field names match Metric fields.


Get year metrics

Trailing-year (or any ≤ 365 day) view at daily resolution.

GET /v1/monitors/:monitor_id/metrics/year?start=2025-10-06&end=2026-10-06&metric=avg
Authorization: Bearer <monitor_token>

Constraints

  • end − start ≤ 365 days
  • metric: avg | max | min | p95

Response 200

"meta": {
  "resolution": "year",
  "metric": "avg",
  "count": 365
}

Which endpoint should I use?

GoalCall
Debug the last few hours.../metrics/raw
Week or month charts.../metrics/hourly
Quarter / multi-month.../metrics/daily
Last year.../metrics/year

Avoid requesting weeks of raw data — at one sample per second that is tens of thousands of points per day per monitor.


Errors

StatuserrorWhen
400invalid_requestMissing start/end, range too wide, bad metric
401unauthorizedInvalid token
403forbiddenToken belongs to another monitor
404not_foundUnknown monitor_id
502upstream_errorTemporary metrics issue

No data in range → 200 with "data": [] and meta.count: 0.


Coming later

Not in the public API yet:

  • Create / delete monitor (use the dashboard)
  • Device ingest API (Orbimon OS only)
  • Alerts history
  • Dedicated “latest sample” shortcut

See also