Connect telemetry
Difficulty: Intermediate. Time: about 30 minutes. Needs: a provisioned tenant API key and a shell.
You will wire real telemetry into your tenant: handle the key correctly, write the agent configuration, post a batch to POST /telemetry, verify it in the console, and finish with the staged connection test that proves each layer independently.
1. Handle the key correctly
Your tenant API key is provisioned per environment by the platform team (how keys work). Before touching an endpoint:
export CONSTELLATION_API_TOKEN='<your key>'
Keep it in a secrets manager or environment variable, never in code or source control. One behavioral rule saves the most pain: treat 401 as fatal in your clients. Five failures from one IP inside five minutes triggers a 15-minute lockout, and a tight retry loop on a bad key will lock out your own gateway.
2. Write the configuration
The console's Settings, API section generates an integration bundle containing a config.toml and an install command; you can also write the file by hand. The full annotated file is documented in Integration bundle; the essentials:
[constellation]
api_url = "https://api.constellation.space"
api_key = "<your key>"
routing = "direct"
[telemetry]
mode = "push"
interval_seconds = 30
content_type = "application/json"
batch_max_records = 1000
Keep the file mode 0600; it holds the key in plaintext. Use direct routing against the real platform; the console-proxy routing option only works under local console development.
The platform authenticates one way only: the x-api-key header. The generated config.toml carries the credential in both [constellation].api_key and [auth].token, and older fleet agent builds and third-party tooling reading the [auth] section have sent it as Authorization: Bearer, which the platform rejects with 401 auth_failed and, repeated, trips the lockout. If a freshly installed agent gets 401 while the same key works in curl via x-api-key, check which header your agent version sends before rotating anything.
3. Post your first batch
Send a small batch by hand before automating anything:
curl -sS -X POST "https://api.constellation.space/telemetry" \
-H "x-api-key: $CONSTELLATION_API_TOKEN" \
-H "content-type: application/json" \
-d '[
{
"measurement": "ground_station",
"time": "2026-07-09T14:30:00Z",
"tags": { "node_id": "GS-SEA-1", "node_type": "ground_station" },
"fields": { "lat": 47.61, "lon": -122.33, "utilization": 0.35 }
},
{
"measurement": "link",
"time": "2026-07-09T14:30:00Z",
"tags": { "link_id": "GS-SEA-1:SAT-0012" },
"fields": { "snr_db": 12.4, "utilization": 0.51 }
}
]'
Expected outcome: HTTP 202 with an ack like {"write_id": "...", "accepted_count": 2, "rejected_count": 0, "rejected_indices": null}. Your tenant is stamped server-side; the body never names it. Limits to design around: 1,000 records per batch, 1 MB per body, and the per-tenant rate limit of 60 requests per minute. Full contract: Telemetry API.
4. Read it back
Topology is the projection of your latest telemetry per entity:
curl -sS -H "x-api-key: $CONSTELLATION_API_TOKEN" \
"https://api.constellation.space/topology?measurement=ground_station&freshness_seconds=900"
Expected outcome: your tenant_key and an entity for GS-SEA-1 whose observed_at matches the sample you wrote.
5. Verify in the console
Open the console, sign in, and switch to live mode. Entities from your telemetry appear on the globe, sparklines fill as samples accumulate, and the connection indicator distinguishes live from stale (no fresh samples in 90 seconds) from disconnected. Under the hood the console reads the same topology projection you just called.
6. Run the staged connection test
The console's "Test connection" (Settings, API) probes four stages separately, and the same shape belongs in your own smoke tests: GET /health reachability, GET /health/telemetry, GET /health/topology, then authenticated GET /topology. Each stage passing isolates the failure domain of the next. A runnable four-language version is in Connection smoke test.
Expected outcome: all four stages green; stage 4 reports your node count and newest sample time.
401 auth_failed: wrong key, wrong environment for the key, or the Bearer-header caveat above.429 auth_lockout: a client looped on a bad key; honorRetry-After(up to 900 seconds) and fix the credential before retrying.413 batch_too_largeorrequest_too_large: split the batch (1,000 records) or the body (1 MB); do not retry as-is.202accepted but topology is empty: yourfreshness_secondswindow may not cover the sample'stime, or you queried a different measurement family. Rememberas_of_utcdefaults to now.503 telemetry_unavailable: the tenant data plane is briefly unreachable; retry after theRetry-Afterhint.
Where next
- Build an integration to turn this into a running poller and writeback loop.
- Errors and limits for the complete error catalog.