Starlink · AsyncAPI Specification
Starlink Telemetry Stream and Device Alerts
Version 2
Event surface for Starlink enterprise device telemetry. Starlink exposes it as a poll-based JSON-over-HTTP stream rather than a broker: the consumer makes continuous small-batch POST requests to /public/v2/telemetry/stream and the server advances a per-credential read index on every successful response. User terminals and routers aggregate and emit every 15 seconds; IP allocation records emit at least every 5 minutes and immediately on change. Stream retention is 8 hours, so a consumer offline longer than that loses data. Device alerts ride inside the same response as an ActiveAlert column of enum codes resolved against the metadata block.
View Spec
View on GitHub
TelecommunicationsUnited StatesSatelliteBroadbandNon-Terrestrial NetworksConnectivityDevice ManagementTelemetryAviationMaritimeEnterpriseAsyncAPIWebhooksEvents
Channels
telemetryStream
Poll with POST. Returns up to batchSize entries collected over at most maxLingerMs milliseconds for every device on the account. Requires the "Device telemetry, View" permission. Not filterable by device.
telemetryQuery
Returns the most recent typed telemetry values for each requested device, keyed by device type then device id. Use this instead of the stream when only the latest state is needed.
Messages
✉
TelemetryBatchRequest
Telemetry batch request
✉
TelemetryBatch
Telemetry batch
✉
TelemetrySnapshot
Telemetry snapshot
Servers
https
production
Starlink Public API V2
AsyncAPI Specification
asyncapi: 3.0.0
info:
title: Starlink Telemetry Stream and Device Alerts
version: '2'
description: >-
Event surface for Starlink enterprise device telemetry. Starlink exposes it as a poll-based
JSON-over-HTTP stream rather than a broker: the consumer makes continuous small-batch POST
requests to /public/v2/telemetry/stream and the server advances a per-credential read index
on every successful response. User terminals and routers aggregate and emit every 15 seconds;
IP allocation records emit at least every 5 minutes and immediately on change. Stream
retention is 8 hours, so a consumer offline longer than that loses data. Device alerts ride
inside the same response as an ActiveAlert column of enum codes resolved against the metadata
block.
contact:
name: Starlink API documentation
url: https://starlink.readme.io/docs/telemetry-api
x-generated: '2026-07-25'
x-method: generated
x-provenance: api-evangelist-derived
x-published-by-provider: false
x-source:
- https://starlink.readme.io/docs/telemetry-api
- https://starlink.readme.io/docs/alerts
- https://starlink.readme.io/reference/post_public-v2-telemetry-stream
x-note: >-
SpaceX publishes no AsyncAPI document. This description was authored by API Evangelist
faithfully from the published telemetry and alerts guides. Every field, enum code and timing
figure below is transcribed from those pages; nothing was invented.
servers:
production:
host: starlink.com
pathname: /api/public/v2
protocol: https
description: Starlink Public API V2
security:
- $ref: '#/components/securitySchemes/serviceAccountBearer'
channels:
telemetryStream:
address: /telemetry/stream
title: Telemetry stream
description: >-
Poll with POST. Returns up to batchSize entries collected over at most maxLingerMs
milliseconds for every device on the account. Requires the "Device telemetry, View"
permission. Not filterable by device.
messages:
telemetryBatchRequest:
$ref: '#/components/messages/TelemetryBatchRequest'
telemetryBatch:
$ref: '#/components/messages/TelemetryBatch'
telemetryQuery:
address: /telemetry/query
title: Telemetry cache query
description: >-
Returns the most recent typed telemetry values for each requested device, keyed by device
type then device id. Use this instead of the stream when only the latest state is needed.
messages:
telemetrySnapshot:
$ref: '#/components/messages/TelemetrySnapshot'
operations:
pollTelemetryStream:
action: receive
channel:
$ref: '#/channels/telemetryStream'
title: Poll the telemetry stream
summary: Continuously poll for the next batch of device telemetry
description: >-
Recommended cadence is roughly 4 requests per minute (batchSize 1000, maxLingerMs 15000).
Each successful response advances this service account's read index; entries lost to a
client crash mid-batch are not re-delivered. A 401 means the bearer token expired.
messages:
- $ref: '#/channels/telemetryStream/messages/telemetryBatch'
queryTelemetryCache:
action: receive
channel:
$ref: '#/channels/telemetryQuery'
title: Query the latest telemetry values
summary: Read the most recent telemetry values per device without consuming the stream
components:
securitySchemes:
serviceAccountBearer:
type: oauth2
description: OIDC client_credentials bearer token from a Starlink V2 service account
flows:
clientCredentials:
tokenUrl: https://starlink.com/api/auth/connect/token
availableScopes: {}
messages:
TelemetryBatchRequest:
name: TelemetryBatchRequest
title: Telemetry batch request
contentType: application/json
payload:
type: object
properties:
batchSize:
type: integer
default: 1000
maximum: 65000
description: Maximum number of entries to return
maxLingerMs:
type: integer
default: 15000
maximum: 65000
description: Maximum milliseconds to spend collecting entries
examples:
- batchSize: 1000
maxLingerMs: 15000
TelemetryBatch:
name: TelemetryBatch
title: Telemetry batch
contentType: application/json
description: >-
Column-indexed telemetry rows. columnNamesByDeviceType must be re-parsed on every
response; column order is not stable across releases.
payload:
type: object
properties:
data:
type: object
properties:
columnNamesByDeviceType:
type: object
description: Device type code to ordered column-name array
values:
type: array
description: Array of telemetry rows; element 0 of each row is the device type code
items:
type: array
metadata:
type: object
properties:
enums:
type: object
properties:
DeviceType:
type: object
description: 'Device type codes: u UserTerminal, r Router, i IpAllocs'
AlertsByDeviceType:
type: object
description: Alert code to alert name, per device type. Authoritative per response.
TelemetrySnapshot:
name: TelemetrySnapshot
title: Telemetry snapshot
contentType: application/json
description: Most recent fully typed telemetry object per device, keyed by device type then device id
payload:
type: object
x-device-types:
- code: u
name: UserTerminal
emit_interval: 15 seconds
id_example: ut12345678-a12b3456-123456c1
columns:
- {name: DeviceType, description: Device type code}
- {name: UtcTimestampNs, description: Nanosecond precision timestamp generated by the device}
- {name: DeviceId, description: Device identifier}
- {name: DownlinkThroughput, unit: Mbps}
- {name: UplinkThroughput, unit: Mbps}
- {name: PingDropRateAvg, description: Average packet loss over the last 15 seconds, 0.0 to 1.0}
- {name: PingLatencyMsAvg, description: Average ping latency from terminal to the Starlink point of presence}
- {name: ObstructionPercentTime, description: Moving average percentage of time obstructed}
- {name: Uptime, unit: seconds}
- {name: SignalQuality, description: SNR extrapolation normalised 0-1 across 0-10 dB}
- {name: H3CellId, description: Terminal location as an H3 cell (h3geo.org)}
- {name: SecondsUntilSwupdateRebootPossible, description: Software deferral countdown; 259200 normally, -1 when deferral is off}
- {name: RunningSoftwareVersion}
- {name: CountryCode, description: ISO 3166-1 alpha-2; XZ in international waters}
- {name: InTerritorialWaters, description: True only in territorial waters of CountryCode}
- {name: ActiveAlert, description: Array of currently active alert codes}
- code: r
name: Router
emit_interval: 15 seconds
id_example: Router-012300205003000000000000
columns_summary: >-
DeviceType, UtcTimestampNs, DeviceId, WifiUptimeS, WifiSoftwareVersion, WifiIsRepeater,
WifiHopsFromController, WifiIsBypassed, InternetPingDropRate, InternetPingLatencyMs,
WifiPopPingDropRate, WifiPopPingLatencyMs, DishPingDropRate, DishPingLatencyMs, Clients,
Clients2Ghz, Clients5Ghz, ClientsEth, WanTxBytes, WanRxBytes, per-band client Rx/Tx rate and
signal strength min/max/avg, DishId, ApiVersion, ActiveAlert
- code: i
name: IpAllocs
emit_interval: at least every 5 minutes, immediately on change
columns:
- {name: DeviceType}
- {name: UtcTimestampNs}
- {name: DeviceId}
- {name: AccountNumber}
- {name: Ipv4, description: Public IPv4 addresses assigned over the last 6 minutes}
- {name: Ipv6Ue, description: Public IPv6 user-equipment /64 addresses}
- {name: Ipv6Cpe, description: Public IPv6 customer-provided-equipment /56 addresses}
tombstone: >-
When a terminal stops requiring public IPs a tombstone message is sent with Ipv4, Ipv6Ue and
Ipv6Cpe empty; afterwards no further IpAllocs messages are sent for that device.
x-alerts:
docs: https://starlink.readme.io/docs/alerts
semantics: >-
An alert fires if its condition was met at least once in the previous 15 seconds and persists
for as long as it is active. The API is stateless and only reports current state. Alert code
to name mapping must be read from metadata.enums.AlertsByDeviceType on each response; codes
may be re-pointed at new names and the mapping is the source of truth.
user_terminal_alerts:
- {code: 50, name: ethernet_slow_10mbps, definition: Ethernet link negotiated to 10 Mbps}
- {code: 51, name: ethernet_slow_100mbps, definition: Ethernet link negotiated to 100 Mbps}
- {code: 52, name: power_supply_thermal_throttling, definition: Power supply is very hot and close to shutting down}
- {code: 53, name: actuator_motor_stuck, definition: The Starlink actuator motor is stuck}
- {code: 54, name: mast_not_vertical, definition: Mast is more than 30 degrees off vertical}
- {code: 55, name: disabled_no_active_account, definition: Account or associated service line is not active}
- {code: 56, name: disabled_too_far_from_service_address, definition: Terminal moved too far from the service address}
- {code: 57, name: disabled_no_service_in_ocean, definition: In the ocean without a service that supports maritime}
- {code: 58, name: disabled_invalid_country, definition: In an unsupported country}
- {code: 59, name: moving_while_not_mobile, definition: Moving above 10 MPH without a mobile service}
- {code: 60, name: disabled_moving_too_fast, definition: Moving faster than the plan allows}
- {code: 61, name: power_disconnect_detected, definition: Previous reboot was caused by loss of power}
- {code: 62, name: pop_change, definition: Point of presence changed; short disconnect and new IP address}
- {code: 63, name: unable_to_align, definition: Unable to align to the desired tilt direction}
- {code: 64, name: high_sky_obstruction, definition: More than 0.5 percent obstructed}
- {code: 65, name: high_sky_obstruction_mobile}
- {code: 66, name: high_time_obstruction, definition: Field of view obstructed more than 0.27 percent of the time}
- {code: 67, name: high_time_obstruction_mobile}
- {code: 79, name: software_update_reboot_pending, definition: Update downloaded; reboot scheduled for 3 AM local time plus or minus 30 minutes}
- {code: 80, name: thermal_shutdown, definition: Max temperature exceeded; service stopped to cool down}
- {code: 81, name: thermal_throttling, definition: High temperature threshold exceeded; performance reduced}
- {code: 83, name: disabled_blocked_country, definition: In a restricted service country}
- {code: 84, name: disabled_data_usage_exceeded_quota, definition: Data usage quota exceeded}
- {code: 89, name: disabled_cell_is_disabled, definition: In a cell that will not get beams}
- {code: 92, name: disabled_unlicensed_country, definition: In an unlicensed country}
- {code: 93, name: disabled_roam_restricted, definition: Roamed too long outside the home country}
- {code: 94, name: disabled_unknown_location, definition: Cannot determine its location}
- {code: 95, name: disabled_account_disabled, definition: The account is disabled}
- {code: 96, name: disabled_unsupported_version, definition: Software version is not supported}
- {code: 97, name: data_overage_rate_limited, definition: Rate limited because priority data is exhausted}
known_issue: >-
Any software version at or above 2025.06.05 incorrectly reports software_update_reboot_pending;
this affects proactive alerts, the dashboard and the telemetry stream
(https://starlink.readme.io/docs/starlink-api-status).
x-other-event-channels:
- name: Proactive alert emails
transport: email
description: >-
Starlink emails proactive alerts to account contacts. There is no API to subscribe, list or
acknowledge them; incident history records several outages where these emails did not send.
webhook: false
x-webhooks:
supported: false
note: Starlink documents no webhook, callback or push-subscription surface of any kind.