Skip to main content

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 /topology on 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_seconds to 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_at per entity between polls.
  • Predictions: poll the cached set every 1 to 5 minutes and use captured_at to detect a new capture. Reserve live=true for 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:

  1. Buffer records as they are produced.
  2. Flush on whichever comes first: 1,000 records or your push interval (the fleet agent uses 30 seconds).
  3. On 202, check rejected_count; resubmit only fixed rejected records, never the whole batch.
  4. On 413, split and resend; on 429/503, wait Retry-After and 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:

StageEnvironmentWhy
Develop the clientdev.api.constellation.spaceContinuous deploy; contract changes land here first.
Experiment with live inferencesandbox.api.constellation.spaceOwn account outside the promotion pipeline; hosts the live SNR serving endpoint.
Pre-production soakstage.api.constellation.spacePromotion target; canary model rollouts land here before prod.
Productionapi.constellation.space or your dedicated <codename>.api.constellation.space domainManual 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.