Integration patterns
The platform API deliberately has no webhooks, no streaming endpoints, and no pagination. Every integration reduces to three verbs: push telemetry batches, poll reads on a cadence, and back off when told to. This page collects the patterns that make those verbs reliable within the platform's limits.
Budget first: know your rate limits
All patterns below must fit inside the rate limits: 30 requests/minute per client IP (before auth, including /health*), 60 requests/minute per tenant sustained, 10 requests/second burst. Add up every poller, prober, and ingest loop sharing a key or an egress IP before choosing cadences.
Polling reads
There is no push channel, so freshness is something you choose:
- Fleet state: poll
GET /topologyon a fixed interval. A 30 to 60 second cadence matches the fleet agent's 30 second push interval; polling faster than your ingest cadence only re-reads the same samples. - Freshness windows: set
freshness_secondsto a small multiple (2 to 3x) of your ingest interval. Too tight and healthy entities flicker out of the response; too wide and stale entities linger, and very wide windows risk the 50,000-row read cap. See Topology. - Change detection: the topology response has no version cursor. Detect change by comparing
observed_atper entity between polls. - Predictions: poll the cached set every 1 to 5 minutes and use
captured_atto detect a new capture. Reservelive=truefor on-demand questions; it is slower and hits the serving backend. See Predictions.
Replay with stepped as_of_utc
Historical reconstruction is a polling loop pointed backwards: step as_of_utc across the window of interest with freshness_seconds matched to the step size, one request per step. A one-hour replay at 60 second steps is 60 requests, which alone consumes a full minute of tenant budget, so pace replay loops (roughly one request per second keeps you under both the burst and sustained limits). Runnable version: Poll topology.
Batching writes
Chunk telemetry into batches of at most 1,000 records and post sequentially:
- Buffer records as they are produced.
- Flush on whichever comes first: 1,000 records or your push interval (the fleet agent uses 30 seconds).
- On
202, checkrejected_count; resubmit only fixed rejected records, never the whole batch. - On
413, split and resend; on429/503, waitRetry-Afterand resend the same batch only if it was cleanly rejected.
The full loop, including the timeout ambiguity where resending risks double-writes (ingest has no dedup), is documented in Telemetry and implemented in Ingest telemetry.
Handling 429 and 503
loop:
response = call()
if 429 or 503:
wait = Retry-After header, else retry_after_seconds from body, else 5s
sleep(wait + jitter) # jitter avoids synchronized retry herds
continue # writes: only if the failed call was cleanly rejected
if other 4xx: stop, fix the request
if network error: exponential backoff (reads only), cap attempts
Two 429 causes need different reactions: rate_limited means slow down and retry; auth_lockout means your IP burned five bad-key attempts, so stop the client and fix the credential, because retrying extends the lockout. Persistent 503 tenant_unavailable or data_plane_unavailable is an escalation to the platform team, not a backoff problem.
Multi-environment strategy
Match your integration lifecycle to the environment ladder:
| Stage | Environment | Why |
|---|---|---|
| Develop the client | dev.api.constellation.space | Continuous deploy; contract changes land here first. |
| Experiment with live inference | sandbox.api.constellation.space | Own account outside the promotion pipeline; hosts the live SNR serving endpoint. |
| Pre-production soak | stage.api.constellation.space | Promotion target; canary model rollouts land here before prod. |
| Production | api.constellation.space or your dedicated <codename>.api.constellation.space domain | Manual promotion gate. |
Keys are per environment, so parameterize both the base URL and the key (CONSTELLATION_API_BASE, CONSTELLATION_API_TOKEN) rather than hardcoding either. Feature schemas can differ across environments (prod pins snr-features-v22, stage v21), so read provenance.feature_schema_version instead of assuming.
Monitoring your integration
Split monitoring into an unauthenticated tier (/health*, safe at high cadence, no lockout risk) and a low-cadence authenticated tier (GET /topology as the key and data plane probe). The Health page defines the split; Monitor the platform and Connection smoke test are drop-in implementations.