Predictions
GET /predictions returns forecasts from a served model for named entities. It reads available predictions from the latest-value store, computes missing results where possible, and returns both results and per-entity errors.
Model families
Choose the model with model_family. Each family forecasts for its own kind of entity and returns its own value fields. See Models for each model's inputs.
model_family | Entity IDs to send | value fields |
|---|---|---|
snr | Link IDs | snr_db_p10, snr_db_p50, snr_db_p90 (dB) |
demand | Pool entity IDs | offered_bytes_p10, offered_bytes_p50, offered_bytes_p99 (bytes) |
A family must be provisioned for your environment.
Authentication requires x-api-key with predictions:read.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
model_family | string | snr | Model family to request. |
link_ids | repeated string | Required | Entity IDs for the chosen family. Send one parameter per entity, up to 100 per request by default. |
horizon_minutes | integer | All available horizons | Restrict results to a horizon served by the model. |
Use the exact IDs carried by your telemetry or fleet data. Duplicate IDs are collapsed, but the request cap is checked before deduplication. Responses name each entity in link_id whatever the family.
curl --fail-with-body -sS \
-H "x-api-key: $CONSTELLATION_API_TOKEN" \
"https://api.constellation.space/predictions?model_family=snr&link_ids=link-a&link_ids=link-b"
Response
This SNR example shows one available forecast and one link without enough telemetry. Other families return the same envelope with their own value fields. Model identifiers and values are illustrative.
{
"model_family": "snr",
"captured_at": "2026-09-10T12:00:00Z",
"model_release_id": "snr-release-example",
"traffic_role": "active",
"items": [
{
"link_id": "link-a",
"horizon_minutes": 1,
"predicted_at": "2026-09-10T11:59:55Z",
"assignment_id": "assignment-example",
"lease_id": "lease-example",
"model_version": "snr-model-example",
"feature_view_id": "snr-features-example",
"model_release_id": "snr-release-example",
"traffic_role": "active",
"value": { "snr_db_p10": 8.99, "snr_db_p50": 9.33, "snr_db_p90": 9.66 }
}
],
"entity_errors": [
{
"entity_id": "link-b",
"code": "insufficient_telemetry",
"message": "Not enough recent telemetry for this link."
}
]
}
| Field | Meaning |
|---|---|
captured_at | When the response set was assembled. Check each item's predicted_at for forecast age. |
items | Available predictions, selected per entity and horizon. |
items[].value | The family's output fields; see Model families. |
items[].demand | Demand only: the pool's identity tags, issue time, and the forecast window. |
items[].model_version, feature_view_id | Model and feature-schema identifiers. Retain these with exported results. |
model_release_id, traffic_role | Release metadata describing the returned items. Set-level metadata may be null or unknown when not shared by all items. |
entity_errors | Entities for which no fresh prediction was produced, with a machine-readable code and explanatory message. |
assignment_id and lease_id are opaque serving identifiers. Do not infer subscription access from model or release identifiers.
Missing and partial results
A 200 does not mean every entity received a fresh forecast. Inspect both items and entity_errors:
- Keep successful items when another entity fails.
- An entity can appear in both arrays. An available result can coexist with a failure to produce a fresh prediction; check its horizon and
predicted_at. no_telemetryorinsufficient_telemetryindicates a missing usable input window.prediction_unavailablecan indicate a failed computation, an in-progress request, a cooldown, or a fill budget. Back off rather than polling in a tight loop.- Empty
itemsand emptyentity_errorscan occur when no model target is provisioned. Confirm model access with Constellation.
Branch on code, not free-text message. Codes can be null, so handle an unspecified per-entity error as well.
Inputs
A family forecasts only from data it can read for the entity. A missing input shows up in entity_errors, never as a zero forecast.
- SNR needs recent
measurement=linktelemetry keyed by the link'sentity_idtag, with fieldssnr_db,elevation_deg,azimuth_deg,slant_range_km, and the link's RF configuration. Use measured or computed geometry for slant range. - Demand needs seven complete days of
measurement=pool_intervalhistory for the pool.
Models lists exactly what to send for each family: measurement, tags, fields, cadence, and history, with an example record.
Polling
Use the same request path for available results and cache misses. Inspect predicted_at to detect a new forecast, batch IDs, and respect request limits. Retrying an unfillable entity faster does not bypass its cooldown.
Errors
| Status | Code | Action |
|---|---|---|
400 | missing_link_ids | Supply at least one link_ids parameter. |
400 | too_many_link_ids | Split the request using the returned max. |
400 | invalid_query_parameter, unknown_query_parameter | Correct the request using the parameter table above. |
404 | predictions_not_enabled | Prediction serving is not enabled in the deployment. |
422 | Validation error | Check parameter types. |
503 | prediction_store_unavailable | The latest-value store could not be read. Honor Retry-After. |
401, 403, 429 | Authentication or request-limit error | Follow Errors and limits. |
For HTTP 200, use the per-entity error handling above rather than HTTP error logic.