GeoSentinel tracks military aircraft activity in real time through a dedicated military-relay microservice that polls the OpenSky Network ADS-B API and filters the full state vector feed down to confirmed military aircraft. The relay is a FastAPI microservice running on port 8002 that maintains its own aircraft identification logic, database, and cache — exposing a clean internal API that the main backend queries per active AOI bounding box. Rather than relying on callsigns (which generate too many false positives) or national hex code ranges (which miss many operated aircraft), the relay uses a monthly-updated database of approximately 10,000 ICAO24 hexadecimal transponder codes confirmed as military operator/owner entries in OpenSky’s own aircraft registry.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/danizd/GeoSentinel/llms.txt
Use this file to discover all available pages before exploring further.
Architecture
MilitaryIngestor queries all active AOI bounding boxes in sequence, deduplicates by flight event ID, and maps each flight to a canonical event.
Military Identification Strategy
The relay determines if an aircraft is military using two criteria, checked in priority order insideis_military():
1. ADS-B Category 7 (highest priority)
The ICAO ADS-B standard defines category 7 as “Military — Fixed Wing.” If an aircraft broadcastscategory=7 in its ADS-B state vector, it is immediately classified as military, regardless of hex code or callsign:
2. ICAO24 Hex Database Lookup (primary method)
The hex database atdata/military_hex.txt contains approximately 10,000 six-character ICAO24 transponder codes compiled from OpenSky’s aircraft registry using military operator and owner keywords. Each line is a single uppercase hex code:
set loaded with @lru_cache(maxsize=1):
Why Not Callsigns or National Hex Ranges
Callsigns likeRCH123 or REACH456 are used extensively, but are also adopted by civilian charters, contractors, and exercise participants — producing unacceptable false-positive rates. The filter comment in the source explicitly notes: “El filtro de callsign se omite deliberadamente: con 10 000+ hex codes de la BD de OpenSky, los callsigns tácticos generan demasiados falsos positivos.”
National hex ranges (e.g., AE0000–AFFFFF for the USA, 43C000–43CFFF for the UK RAF) are defined in config.py and available via is_hex_military_by_range(), but are not used by is_military() — national blocks contain civilian government, coast guard, and other non-combat aircraft that would inflate military event counts.
The callsign list (
CALLSIGN_PREFIXES_FULL) in config.py contains 80+ verified military prefixes from community-verified FR24 data (RAF, Luftwaffe, IAF, NATO AWACS, USAF, USN, etc.) and is maintained for future use, but is not part of the active is_military() classification path.Monthly Database Auto-Update
At relay startup, GeoSentinel checksdata/military_hex.txt and rebuilds it if any of the following conditions are met:
- The file does not exist
- The file is more than 30 days old
- The file contains fewer than 1,000 entries (indicating a corrupt or truncated download)
operator and owner fields, and extracts entries matching MILITARY_OPERATOR_KEYWORDS. The resulting ICAO24 hex codes are written to data/military_hex.txt (~10,000 entries after filtering).
Rate Limiting
The relay enforces a 1 request/second ceiling on all OpenSky API calls, matching OpenSky’s free tier rate limit. Requests are throttled at the relay layer so the main backend can query the relay as frequently as needed without triggering 429s upstream.Event ID Generation
Each military flight event is assigned a time-bucketed ID that deduplicates across the 60-second poll interval:Severity and Anomaly Escalation
Base severity for military flights is3.0. The ingestor escalates severity under three conditions:
| Condition | Severity floor |
|---|---|
Flight is within 50 km of an active conflict incident (check_incident_proximity) | 7.0 |
Flight is flagged isInteresting=true by the relay | 6.0 |
≥ 3 military aircraft within 100 km radius (check_cluster) | 5.0 |
MilitaryIngestor, not in the relay itself.
Frontend API Endpoint
The main backend exposes military flight data through:MilitaryIngestor.fetch_from_relay():
flights array and a clusters array. If relay data is stale (cache older than TTL), the response includes X-Stale: true and the ingestor logs a warning.
Debug Endpoint
The relay exposes a/debug endpoint on port 8002 for diagnostics:
Environment Variables
Starting the Relay
data/military_hex.txt is missing, stale, or undersized.
Force a Manual Database Update
To immediately rebuilddata/military_hex.txt from the latest OpenSky aircraft database:
OpenSky Network data is subject to the OpenSky Terms of Use. Non-commercial use is permitted. Individual ICAO24 hex codes (
hexCode field) are never exposed in GeoSentinel’s public /v1/incidents API — only aggregated event data is surfaced.