Base URL:
http://localhost/api(via Nginx reverse proxy) Direct (internal):http://sovereign-backend:8000Interactive Docs:http://localhost/api/docs(Swagger UI) Framework: FastAPI (Python)
The API currently does not require authentication tokens. It is designed to run on a local trusted network. Ensure Nginx is not exposed directly to the public internet without adding an authentication layer.
Returns a simple liveness check.
Response:
{ "status": "ok" }Real-time entity stream. Connect to receive all entity position updates as they arrive from the Redpanda Kafka bus.
ws://localhost/api/tracks/live
Message Format: Each message is a JSON string containing a TAK event (see TAK Protocol Reference):
{
"uid": "a1b2c3",
"type": "a-f-A-C-F",
"how": "m-g",
"time": 1710000000000,
"start": "2026-03-12T18:00:00Z",
"stale": "2026-03-12T18:02:00Z",
"point": { "lat": 45.52, "lon": -122.68, "hae": 10668, "ce": 10, "le": 10 },
"detail": { "contact": { "callsign": "UAL123" }, "track": { "course": 270, "speed": 245 } }
}- The WebSocket connection receives all entity domains (aviation, maritime, orbital, RF) as a unified stream.
- Client-side filtering by domain/type is performed in the frontend layer selection logic.
- The connection is broadcast — no subscription filtering is available at the WebSocket level.
Returns historical track points for a specific entity.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
entity_id |
string | Entity UID (e.g., ICAO hex a1b2c3, MMSI 123456789, or SAT-25544 for a satellite) |
Query Parameters:
| Parameter | Type | Default | Constraints | Description |
|---|---|---|---|---|
limit |
int | 100 |
1 – MAX_LIMIT | Maximum number of track points to return |
hours |
int | 24 |
1 – MAX_HOURS | Lookback window in hours |
Data source routing: Aircraft and vessel entities (
entity_idnot starting withSAT-) are served from thetrackshypertable (72-hour retention). Satellite entities (SAT-*) have no stored position history — positions are computed on-demand via SGP4 from the current TLE in thesatellitestable. Thehoursandlimitparameters control the time window and point density of the computed track.
Response: Array of track objects ordered by time descending:
[
{
"time": "2026-03-12T17:45:00Z",
"lat": 45.52,
"lon": -122.68,
"alt": 10668.0,
"speed": 245.3,
"heading": 270.5,
"meta": { "callsign": "UAL123", "classification": { ... } }
}
]Note: For satellite entities (
SAT-*),metais alwaysnull. Satellite metadata (name, category, constellation, TLE) is available viaGET /api/orbital/passesandGET /api/orbital/groundtrack/{norad_id}.
Search for entities by UID or callsign (substring match).
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
q |
string | (required) | Search query (min 2 chars, max 100 chars) |
limit |
int | 10 |
Maximum results |
Response: Array of most-recent-position objects per matched entity:
[
{
"entity_id": "a1b2c3",
"type": "a-f-A-C-F",
"last_seen": "2026-03-12T17:45:00Z",
"lat": 45.52,
"lon": -122.68,
"callsign": "UAL123",
"classification": { "platform": "fixed_wing", "affiliation": "civilian" }
}
]Satellite results: Matches are sourced directly from the
satellitesTLE catalogue by('SAT-' || norad_id) ILIKEorname ILIKE.callsignis the satellite name,classificationis alwaysnull, and thelat/lonfields reflect the current computed position (SGP4 propagated at query time). Bothtracksandsatellitesare searched in parallel and results are combined.
Retrieve all track points within a time window for historical replay.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
start |
string | ISO 8601 start timestamp (e.g., 2026-03-12T10:00:00Z) |
end |
string | ISO 8601 end timestamp |
limit |
int | Maximum track points (default: 1000, max: MAX_REPLAY_LIMIT) |
Constraints:
endmust be afterstart- Time window cannot exceed
MAX_REPLAY_HOURS
Data source: Results are a UNION of
tracks(72-hour retention) and thetrackshypertable. Satellite track points older than 72 hours (ADS-B/AIS) will not appear in replay results.
Response: Array of track points ordered by time ascending, including all entity types within the time window. Satellite rows (type: "a-s-K") always have meta: null:
[
{
"time": "2026-03-12T10:00:05Z",
"entity_id": "a1b2c3",
"type": "a-f-A-C-F",
"lat": 45.50,
"lon": -122.70,
"alt": 9144.0,
"speed": 238.0,
"heading": 265.0,
"meta": { "callsign": "UAL123", "classification": { ... } }
},
{
"time": "2026-03-12T10:00:10Z",
"entity_id": "SAT-25544",
"type": "a-s-K",
"lat": 51.50,
"lon": -0.12,
"alt": 418000.0,
"speed": 7660.0,
"heading": 42.1,
"meta": null
}
]Performs AI-powered tactical analysis on a track entity using the configured LLM.
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
uid |
string | Entity UID to analyze |
Request Body:
{
"lookback_hours": 6
}Response: Server-Sent Events (SSE) stream — the AI assessment is streamed token-by-token.
data: Based on the telemetry data for entity a1b2c3 (UAL123)...
data: The aircraft maintained a consistent westbound heading...
data: No anomalies detected.
Available AI Models (configured via /api/config/ai):
| Model ID | Label | Provider |
|---|---|---|
deep-reasoner |
Claude 3.5 Sonnet | Anthropic (cloud) |
public-flash |
Gemini 1.5 Flash | Google (cloud) |
secure-core |
LLaMA3 (Ollama) | Local |
Get the current active surveillance area (AOR).
Response:
{
"lat": 45.5152,
"lon": -122.6784,
"radius_nm": 150,
"updated_at": "2026-03-12T18:00:00Z"
}If not previously set, returns the CENTER_LAT / CENTER_LON / COVERAGE_RADIUS_NM defaults from the environment.
Update the active surveillance area. Immediately notifies all pollers via Redis pub/sub.
Request Body:
{
"lat": 38.8977,
"lon": -77.0365,
"radius_nm": 100
}Constraints: lat ∈ [-90, 90], lon ∈ [-180, 180], radius_nm ∈ [10, 300]
Response:
{
"status": "ok",
"active_mission": { "lat": 38.8977, "lon": -77.0365, "radius_nm": 100 }
}Returns available AI models and the currently active selection.
Response:
{
"active_model": "deep-reasoner",
"available_models": [
{ "id": "deep-reasoner", "label": "Claude 3.5 Sonnet", "provider": "Anthropic", "local": false },
{ "id": "public-flash", "label": "Gemini 1.5 Flash", "provider": "Google", "local": false },
{ "id": "secure-core", "label": "LLaMA3 (Ollama)", "provider": "Local", "local": true }
]
}Switch the active AI model.
Request Body:
{ "model_id": "secure-core" }Valid model IDs: deep-reasoner, public-flash, secure-core
Returns which optional features are enabled based on environment credentials.
Response:
{
"radioref_enabled": false
}Query RF infrastructure sites within a geographic area.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
lat |
float | (required) | Center latitude |
lon |
float | (required) | Center longitude |
radius_nm |
float | 150 |
Search radius in nautical miles (1–2500) |
services |
string[] | [] |
Filter by service: ham, noaa, public_safety, etc. |
modes |
string[] | [] |
Filter by mode: FM, DMR, P25, D-STAR, Fusion, etc. |
emcomm_only |
bool | false |
Return only EMCOMM-designated stations |
source |
string | (all) | Filter by source: ard, noaa_nwr, radioref |
Results are ordered by distance from the query point. Max 5,000 results. Responses cached in Redis for 1 hour.
Response:
{
"count": 247,
"results": [
{
"id": "uuid",
"source": "ard",
"callsign": "W7ABC",
"output_freq": 146.520,
"input_freq": 146.520,
"tone_ctcss": 100.0,
"modes": ["FM"],
"service": "ham",
"emcomm_flags": ["ARES"],
"lat": 45.51,
"lon": -122.67,
"city": "Portland",
"state": "OR"
}
]
}Alias for /api/rf/sites filtered to service=ham. Accepts radius in miles (converted internally to nm).
Query Parameters: lat, lon, radius (miles, default 75)
Predict upcoming satellite passes visible from an observer location.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
lat |
float | (required) | Observer latitude |
lon |
float | (required) | Observer longitude |
hours |
int | 6 |
Prediction window (1–48 hours) |
min_elevation |
float | 10.0 |
Minimum elevation angle in degrees (0–90) |
norad_ids |
string | (all) | Comma-separated NORAD IDs to filter |
category |
string | (all) | Filter by category: gps, weather, intel, etc. |
constellation |
string | (all) | Filter by constellation: Starlink, GPS, Iridium, etc. |
limit |
int | (none) | Maximum passes to return (1–500) |
Note: Category
commsrequires specifyingnorad_idsorconstellation— the fleet is too large for an unconstrained scan.
Results are cached in Redis for 5 minutes.
Response: Array of pass objects sorted by AOS:
[
{
"norad_id": "25544",
"name": "ISS (ZARYA)",
"category": "leo",
"aos": "2026-03-12T19:15:00Z",
"tca": "2026-03-12T19:20:30Z",
"los": "2026-03-12T19:26:00Z",
"max_elevation": 72.4,
"aos_azimuth": 315.2,
"los_azimuth": 135.8,
"duration_seconds": 660,
"points": [
{ "t": "2026-03-12T19:15:00Z", "az": 315.2, "el": 10.0, "slant_range_km": 1247.3 }
]
}
]Compute the sub-satellite ground track for one orbit.
Path Parameters: norad_id — NORAD catalog number (string)
Query Parameters:
| Parameter | Default | Range | Description |
|---|---|---|---|
minutes |
90 |
1–1440 | Propagation window in minutes |
step_seconds |
30 |
5–300 | Time step between points |
Response:
[
{ "t": "2026-03-12T18:00:00Z", "lat": 51.6, "lon": -120.3, "alt_km": 421.2 }
]Returns satellite counts grouped by category.
Response:
{ "gps": 120, "weather": 85, "comms": 7500, "intel": 210, "other": 480, "total": 8395 }Returns satellite counts grouped by category and constellation.
Response:
{
"comms": { "Starlink": 6800, "OneWeb": 580, "Iridium": 75 },
"intel": { "RADARSAT": 3, "Spire": 80, "Planet": 120 }
}Returns submarine cable route GeoJSON (sourced from TeleGeography, cached in Redis).
Response: GeoJSON FeatureCollection with cable LineString geometries.
Returns submarine cable landing station GeoJSON.
Response: GeoJSON FeatureCollection with landing station Point geometries.
Returns active internet outage data (sourced from IODA, cached in Redis, refreshed every 30 minutes).
Each outage feature includes a nearby_cable_landings array listing submarine cable landing point names within 300 km of the outage centroid.
Response: GeoJSON FeatureCollection with outage Point features:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "outage-EG",
"region": "Egypt",
"country_code": "EG",
"severity": 61.2,
"datasource": "IODA_OVERALL",
"nearby_cable_landings": ["Alexandria (Egypt)", "Port Said (Egypt)"]
},
"geometry": { "type": "Point", "coordinates": [30.8, 26.8] }
}
]
}Returns the current Kp-index value and 24-hour history series.
Response:
{
"current": {
"kp": 3.3,
"kp_fraction": 3.33,
"storm_level": "unsettled",
"time": "2026-04-03T12:00:00Z",
"fetched_at": "2026-04-03T12:05:00Z"
},
"history": [
{ "time": "2026-04-02T12:00:00Z", "kp": 2.0, "storm_level": "quiet" }
]
}Returns the NOAA 1-hour auroral oval forecast as a GeoJSON FeatureCollection. Each feature is a Point with an aurora property (0–100 intensity percentage). Only points with intensity ≥ 5% are included.
Quick-summary endpoint for HUD widgets.
Response:
{
"kp": 3.3,
"storm_level": "unsettled",
"aurora_active": true,
"gps_degradation_risk": "low",
"time": "2026-04-03T12:00:00Z"
}gps_degradation_risk |
Condition |
|---|---|
low |
Kp < 5 |
moderate |
5 ≤ Kp < 7 |
high |
Kp ≥ 7 |
Returns current NOAA Space Weather Scale levels (R/S/G) and the active signal-loss suppression state.
Response:
{
"scales": {
"0": {
"R": { "Scale": "R3", "Text": "Strong" },
"S": { "Scale": "S0", "Text": "None" },
"G": { "Scale": "G0", "Text": "None" }
}
},
"suppression": {
"active": true,
"reason": "R3 Radio Blackout",
"r_scale": "R3",
"g_scale": "G0",
"expires_at": "2026-04-03T13:10:00Z",
"set_at": "2026-04-03T12:00:00Z"
},
"fetched_at": "2026-04-03T12:05:00Z"
}suppression is null when no R3+/G3+ event is active. When suppression.active is true, satellite signal-loss anomaly detection is suspended system-wide to prevent false-positive jamming alerts.
Three specialized domain agent endpoints provide persona-driven risk assessments that fuse multi-INT data with environmental context.
Air Intelligence Officer persona. Fuses ADS-B telemetry, emergency squawk codes, NWS weather alerts, and Kp-index GPS risk.
Request body:
{ "h3_region": "872830828ffffff", "lookback_hours": 24 }Response:
{
"domain": "air",
"h3_region": "872830828ffffff",
"narrative": "Air domain assessment for ...: 14 ADS-B tracks observed...",
"risk_score": 0.18,
"indicators": [
"Emergency squawk codes active: 1 aircraft",
"Possible holding patterns: 3 UIDs with ≥5 observations"
],
"context_snapshot": {
"adsb_entity_count": 14,
"emergency_squawk_count": 1,
"kp_index": 2.3,
"nws_alerts": { "count": 42, "severe_count": 3, "extreme_count": 0 }
}
}Maritime Domain Awareness (MDA) Specialist persona. Fuses AIS vessel telemetry, NDBC wave height observations, and IODA internet outage / submarine cable landing correlation.
Request body:
{ "h3_region": "872830828ffffff", "lookback_hours": 24 }Response:
{
"domain": "sea",
"h3_region": "872830828ffffff",
"narrative": "Sea domain assessment for ...: 8 AIS tracks observed...",
"risk_score": 0.31,
"indicators": [
"High sea state: max wave height 5.2m (NDBC)",
"Internet outages near submarine cable landings: 2 regions affected"
],
"context_snapshot": {
"ais_entity_count": 8,
"max_wave_height_m": 5.2,
"cable_correlated_outages": 2
}
}Space Weather / Orbital Analyst persona. Fuses Kp-index, NOAA R/S/G scale levels, SatNOGS signal loss events, and the active suppression state.
Request body:
{ "h3_region": "872830828ffffff", "lookback_hours": 24 }Response:
{
"domain": "orbital",
"h3_region": "872830828ffffff",
"narrative": "Orbital/space-weather assessment for ...: Kp=7.0 (G2)...",
"risk_score": 0.62,
"indicators": [
"Significant geomagnetic storm: Kp=7.0 (G2 - Moderate)",
"Radio Blackout R3: HF comms degraded",
"Signal-loss suppression active: R3 Radio Blackout"
],
"context_snapshot": {
"kp_index": 7.0,
"storm_level": "G2 - Moderate",
"noaa_scales": { "R": "R3", "G": "G2", "S": "S0" },
"signal_loss_suppression": { "active": true, "reason": "R3 Radio Blackout" }
}
}Returns the current state of all H3 polling cells used by the ADS-B poller.
Response: Array of cell state objects:
[
{
"cell": "8a2a1072b59ffff",
"priority": 145,
"last_polled": "2026-03-12T18:01:00Z",
"aircraft_count": 12
}
]| Code | Meaning |
|---|---|
400 |
Invalid request parameters (bad timestamp, out-of-range value, etc.) |
404 |
Entity not found (e.g., NORAD ID not in satellite table) |
422 |
Malformed TLE or data format error |
503 |
Database or Redis not ready (service starting up) |
500 |
Internal server error (check logs) |