Skip to content
SatelliteIndex

Methodology

How the index is built

Every value on SatelliteIndex is either a sourced fact with provenance or a derived label with a versioned rule. This page documents the rules — from the raw upstream payload to the position drawn on the globe — so you can decide how much to trust each number.

Sources and licenses: /sources · Live freshness: /status/data · Machine-readable: /api/v1/methodology· definitions fetched 11 Sept 2026 20:32 UTC

01

Data pipeline

The site is never coupled to a third-party feed. Every value passes through the same chain, and each stage keeps what the previous one produced:

  1. Connector — a scheduled worker per upstream feed (celestrak_gp, celestrak_groups, celestrak_satcat, derived_analytics). Each run is recorded with duration, record counts, a payload hash and any error; repeated failures open a circuit breaker.
  2. Raw snapshot — the exact upstream payload is stored gzip-compressed on disk and indexed in raw_records before anything is parsed. Only payloads whose hash changed are processed; unchanged responses are logged as such.
  3. Normalize — rows are parsed into a common shape (identifiers, names, dates, element sets). Suspiciously short responses (for example a catalog with far fewer than 50 000 rows) are rejected as truncated rather than treated as “no data”.
  4. Entity resolution — each normalized row is matched to an existing canonical object (next section) or creates a new one. Ambiguous matches go to a manual review queue.
  5. Canonical store — one row per object in satellites, an append-only orbital_elements history with orbital_state pointing at the latest epoch, field-level history and field_provenance (source, observation time, confidence) for every accepted value. Objects missing from an upstream response are never deleted.
  6. Derived — materialized statistics, constellation/operator/country aggregates, the search index and detected events are refreshed by derived_analytics (hourly) using the versioned metric definitions below.
  7. API → web — the public JSON API reads only the canonical and derived layers; the website is a client of that API. Positions are computed at request time (see orbit calculation).

02

Source priorities

Sources carry a numeric priority; when two sources describe the same field the higher-priority value is kept and the other is still recorded in provenance. In practice each field family has one primary source today:

FieldPrimary sourceNote
Orbital elements (mean motion, eccentricity, inclination, RAAN, argument of perigee, mean anomaly, B*)CelesTrak GPOMM element sets from the `active` GP group; every epoch is appended to the orbital history, the latest becomes the orbital state.
Catalog identity (NORAD, COSPAR, object name, object type)CelesTrak SATCATFull catalog snapshot, diffed against the canonical table on every run.
Status (operational status code), decay dateCelesTrak SATCATOPS_STATUS_CODE mapped to the canonical status; a decay date always wins.
Owner code, launch date, launch siteCelesTrak SATCATOwner codes are resolved to countries and organizations with the curated owner-code table.
Launches (international designator prefix YYYY-NNN)Derived from SATCATGrouped from the COSPAR designator of the catalogued objects; counts refreshed after each SATCAT run.
Constellation membership, tagsCelesTrak GP groups, then SatelliteIndex name patternsA group membership is source-backed; a regular-expression match on the name is derived.
Orbit class, mission type, operator/country from owner code, activity score, orbital densitySatelliteIndex (derived / curated)Versioned metric definitions — see the methodology page.

03

Entity resolution

Matching an incoming row to a canonical object follows a strict priority; the first rule that yields exactly one candidate wins:

  1. NORAD catalog number — if the row has a NORAD id already known, it is the same object.
  2. COSPAR designator — only when the row has no NORAD id, and only if exactly one canonical object carries that designator.
  3. Exact normalized name — only when the row has no NORAD id, against canonical objects that also lack one, and only if the name is unique.
  4. Create — otherwise a new canonical object is created with a ULID and a slug (name-norad, de-duplicated with a numeric suffix).

Anything ambiguous — a COSPAR id that maps to several objects, a name shared by several objects, or a NORAD id that appears alongside a different existing designator — is never merged automatically. It is written to manual_review_queue with both candidates and a confidence; an operator decides merge, keep separate or dismiss. Merges move aliases, identifiers and element history to the kept object and are journaled in entity_merges with a snapshot of the removed row, so they can be audited or reversed.

04

Orbit calculation

Positions are propagated with SGP4 (the python-sgp4 implementation of the Vallado et al. reference code, vectorised with SatrecArray) using the WGS-72 gravity constants — the model the element sets were fitted against. Inputs are the OMM element sets from CelesTrak (epoch, mean motion, eccentricity, inclination, RAAN, argument of perigee, mean anomaly, B*, first derivative of mean motion).

SGP4 yields a position vector in the TEME frame. It is rotated to Earth-fixed coordinates (ECEF) about the Z axis by the Greenwich Mean Sidereal Time of the requested instant (UT1 ≈ UTC; polar motion ignored, ≈ 10 m), then converted to geodetic latitude, longitude and altitude on the WGS84 ellipsoid by iteration. Velocity is the norm of the TEME velocity vector.

Derived geometry shown on satellite pages comes from the same element set: semi-major axis a = (μ / n²)^1/3 with μ = 398 600.4418 km³/s², perigee/apogee = a(1 ∓ e) − 6 378.137 km, period = 1440 / n minutes.

Accuracy

SGP4 is an analytical mean-element model: typical along-track error is of the order of a kilometre at epoch and grows by kilometres per day, faster for low, high-drag orbits and after manoeuvres. Positions shown on this site are therefore indicative: good for “where is it over the Earth right now”, not for pointing, conjunction or reentry work. Every position carries the epoch it was propagated from and its age.

Positions are computed on demand and never stored: the propagator keeps the latest element set of every object in memory and answers batch and single-object requests with a 30-second cache. Only element sets are persisted.

05

Status classification

SATCAT operational status code (+/P → ACTIVE, B/S/X → INACTIVE, D or decay date → DECAYED, ? → UNKNOWN). Objects without a SATCAT code but present in the CelesTrak `active` GP group are ACTIVE; debris and rocket bodies still on orbit are INACTIVE.
SATCAT codeMeaningCanonical status
+OperationalACTIVE
PPartially operationalACTIVE
BBackup / standbyINACTIVE
SSpareINACTIVE
XExtended missionINACTIVE
DDecayedDECAYED
?UnknownUNKNOWN
(blank)No code publishedUNKNOWN

Two overrides apply after the code lookup, in this order: a decay date always produces DECAYED; debris and rocket bodies with no code are INACTIVE rather than UNKNOWN (they cannot be “operational”). Payloads present in the CelesTrak active GP group but lacking a SATCAT code are considered ACTIVE. Status changes emit decommission / activation events and are kept in the field history.

06

Orbit class

Derived from the latest element set: GEO = period 1436±30 min, e<0.05, i<20°; HEO = e>0.25 and apogee>35 000 km; LEO = apogee<2 000 km; MEO = 2 000 km≤perigee and apogee<35 586+2 000 km; else OTHER.

The rule is evaluated on the latest element set (or, for objects without GP data, on the SATCAT apsides with eccentricity estimated from perigee and apogee). Implementation order, as in orbital/elements.py:

classify_orbit
if apogee or perigee missing                                → OTHER
if |period − 1436.07 min| ≤ 30 and e < 0.05 and i < 20°     → GEO
if e > 0.25 and apogee > 35 000 km                          → HEO
if apogee < 2 000 km                                        → LEO
if perigee ≥ 2 000 km and apogee < 35 786 + 2 000 km:
    if |period − 1436.07| ≤ 60                              → GEO   (inclined / drifting geosynchronous)
    else                                                    → MEO
if |period − 1436.07| ≤ 60 and e < 0.1                      → GEO
else                                                        → OTHER

OTHER therefore collects transfer orbits, highly eccentric non-HEO objects and anything with an apogee below 2 000 km but a perigee above it — impossible by definition, so effectively it is the “does not fit” bucket. Orbit class is a derived label, versioned as metric orbit_class.

07

Constellation membership

Membership is assigned in two tiers. CelesTrak GP groups first: an object listed in a thematic group mapped to a constellation (for example starlink, oneweb, kuiper) is a source-backed member (method: celestrak_group). Documented name patterns second: payloads not covered by a group are matched against the regular expressions of the curated registry (method: name_pattern, derived). Membership history is kept with since/until dates; a member is never removed just because a group response was short.

The table below is the live registry — the exact patterns and groups the classifier uses right now.

ConstellationServiceCelesTrak groupsName patterns
Amazon Leo (Project Kuiper)communicationskuiper^KUIPER^AMAZON LEO
AST SpaceMobile BlueBirdcommunicationsnone^BLUEBIRD^BLUEWALKER
Astrocastiotnone^ASTROCAST
BeiDounavigationbeidou^BEIDOU
BlackSky Global / Gen-3earth-observationnone^BLACKSKY^GLOBAL-\d+$
Capella SARearth-observationnone^CAPELLA^ACADIA
Cartosat / RISAT / EOSearth-observationnone^CARTOSAT^RISAT^EOS-\d^RESOURCESAT^OCEANSAT
CentiSpacenavigationnone^CENTISPACE
ChinaSat / Zhongxingcommunicationsnone^CHINASAT^ZHONGXING^ZX-
Copernicus Sentinelearth-observationnone^SENTINEL
EchoStar / Jupitercommunicationsnone^ECHOSTAR^JUPITER \d^HUGHES
Eutelsat GEO fleetcommunicationseutelsat^EUTELSAT^HOTBIRD^KONNECT^EUTE
Fengyunweathernone^FENGYUN^FY-
Galileonavigationgalileo^GSAT\d{4}^GALILEO
Gaofen (CHEOS)earth-observationnone^GAOFEN
Geely GEESATiotnone^GEESAT
Globalstarcommunicationsglobalstar^GLOBALSTAR
GLONASSnavigationglo-ops^COSMOS .*\(GLONASS^GLONASS
GOESweathergoes^GOES
Gonetscommunicationsnone^GONETS
GPS (NAVSTAR)navigationgps-ops^NAVSTAR^GPS
GSAT / INSATcommunicationsnone^GSAT-^INSAT^CMS-\d
Guowang (Hulianwang)communicationshulianwang^HULIANWANG^GUOWANG
HawkEye 360earth-observationnone^HAWK-?\d^HAWKEYE
Himawariweathernone^HIMAWARI
Hongyun / Yuanxincommunicationsnone^HONGYUN^YUANXIN
ICEYE SARearth-observationnone^ICEYE
Intelsat fleetcommunicationsintelsat^INTELSAT^IS-\d^GALAXY \d^HORIZONS
International Space Stationstationstations^ISS \(^ISS DEB^CREW DRAGON^CYGNUS^PROGRESS-MS^SOYUZ-MS^DRAGON ^HTV^CSS \(
IRIDEearth-observationnone^IRIDE
Iridium NEXTcommunicationsiridium-NEXT^IRIDIUM
Jilin-1earth-observationnone^JILIN
Kinéis IoTiotnone^KINEIS
Kosmos (Russian military / government)militarynone^COSMOS \d+$^COSMOS \d+ \(
Landsatearth-observationnone^LANDSAT
Lynk Globalcommunicationsnone^LYNK
Maxar WorldView / Legionearth-observationnone^WORLDVIEW^GEOEYE^WV LEGION^WORLDVIEW LEGION
Metop / Meteosatweathernone^METOP^METEOSAT^MTG-
Myriotaiotnone^MYRIOTA
NavIC (IRNSS)navigationnone^IRNSS^NVS-
NOAA POES / JPSSweathernoaa^NOAA \d^SUOMI NPP^JPSS
OneWebcommunicationsoneweb^ONEWEB
ORBCOMMiotorbcomm^ORBCOMM
Planet Flock (Dove)earth-observationplanet^FLOCK^DOVE
Planet Pelican / Tanagerearth-observationnone^PELICAN^TANAGER
Planet SkySatearth-observationnone^SKYSAT
Pléiades / Pléiades Neoearth-observationnone^PLEIADES
Praetorian (Firefly / military rideshare)militarynone^PRAETORIAN
Qianfan (Thousand Sails / SpaceSail)communicationsqianfan^QIANFAN
QZSS (Michibiki)navigationnone^QZS
RADARSATearth-observationnone^RADARSAT^RCM-
Rassvet (Bureau 1440)communicationsnone^RASSVET
Sateliotiotnone^SATELIOT
Satellogic NewSat (Ñusat)earth-observationnone^NUSAT^ÑUSAT^NEWSAT
SBAS / augmentationnavigationsbasnone
SES GEO fleetcommunicationsses^SES-^SES ^ASTRA ^NSS-^AMC-^QUETZSAT
SES O3b / O3b mPOWERcommunicationsnone^O3B
Shijiantechnologynone^SHIJIAN
Shiyantechnologynone^SHIYAN
SiriusXMcommunicationsnone^SIRIUS^XM-^SXM-
SITRO-AISiotnone^SITRO
Spire Lemurearth-observationspire^LEMUR
Starlinkcommunicationsstarlink^STARLINK
Swarm (SpaceBEE)iotswarm^SPACEBEE
Telesat (Anik / Telstar / Lightspeed)communicationstelesat^ANIK^TELSTAR^NIMIQ^LIGHTSPEED^LEO VANTAGE
Tianmu-1weathernone^TIANMU
Tianqiiotnone^TIANQI
TJS (Tongxin Jishu Shiyan)militarynone^TJS
Umbra SARearth-observationnone^UMBRA
USA (classified US military payloads)militarynone^USA \d+$^USA \d+ \(
Viasat / Inmarsat fleetcommunicationsnone^VIASAT^INMARSAT^WILDBLUE
Yaoganmilitarynone^YAOGAN

72 constellations in the registry.

08

Mission type

Mission type is derived, in this order of preference (services/classify.py):

  1. the service type of the matched constellation (communications, earth-observation, navigation, iot…);
  2. otherwise the object type when it is decisive: rocket bodies → rocket-body, debris → debris, stations → station;
  3. otherwise a documented name pattern from the curated registry (for example weather, GNSS or science families);
  4. otherwise unknown. A later run never downgrades a known mission type to unknown.

09

Launches

No launch feed is ingested yet. Launches are derived from international designators: the first eight characters of a COSPAR id (YYYY-NNN) identify the launch, so every object sharing that prefix is attached to one launch row. The launch date and site are the earliest date and the site reported for those objects in SATCAT; the “primary” payload is the object whose piece letter is A; payload, object and on-orbit counts are recomputed after every catalog run. Objects with no COSPAR id (analyst objects) belong to no launch and are flagged.

10

Owner codes

SATCAT identifies the responsible party of every object with a short owner code. We map each code to a country (ISO 3166) and, when the owner is an organization, agency or intergovernmental body, to an operator entity. Joint programmes map to several countries’ programmes but a single primary country when one is defined. Unmapped codes raise an UNKNOWN_COUNTRY quality flag instead of guessing.

Countries104 codes
CodeNameCountry
ALGAlgeriaDZ
ANGAngolaAO
ARGNArgentinaAR
ARMArmeniaAM
ASRAAustriaAT
AUSAustraliaAU
AZERAzerbaijanAZ
BELBelgiumBE
BELABelarusBY
BERMBermudaBM
BGDBangladeshBD
BHRBahrainBH
BHUTBhutanBT
BOLBoliviaBO
BRAZBrazilBR
BULBulgariaBG
BWABotswanaBW
CACanadaCA
CHLEChileCL
CISCommonwealth of Independent States (former USSR)RU
COLColombiaCO
CRICosta RicaCR
CZCHCzech RepublicCZ
DENDenmarkDK
DJIDjiboutiDJ
ECUEcuadorEC
EGYPEgyptEG
ESTEstoniaEE
ETHEthiopiaET
FINFinlandFI
FRFranceFR
GERGermanyDE
GHAGhanaGH
GRECGreeceGR
GUATGuatemalaGT
HRVCroatiaHR
HUNHungaryHU
INDIndiaIN
INDOIndonesiaID
IRANIranIR
IRAQIraqIQ
IRLIrelandIE
ISRAIsraelIL
ITItalyIT
JORJordanJO
JPNJapanJP
KAZKazakhstanKZ
KENKenyaKE
KWTKuwaitKW
LAOSLaosLA
LKASri LankaLK
LTULithuaniaLT
LUXELuxembourgLU
MAMoroccoMA
MALAMalaysiaMY
MCOMonacoMC
MDAMoldovaMD
MEXMexicoMX
MMRMyanmarMM
MNEMontenegroME
MNGMongoliaMN
MUSMauritiusMU
NETHNetherlandsNL
NIGNigeriaNG
NKORNorth KoreaKP
NORNorwayNO
NPLNepalNP
NZNew ZealandNZ
PAKIPakistanPK
PERUPeruPE
POLPolandPL
PORPortugalPT
PRCPeople's Republic of ChinaCN
PRYParaguayPY
QATQatarQA
ROCTaiwanTW
ROMRomaniaRO
RPPhilippinesPH
RWARwandaRW
SAFRSouth AfricaZA
SAUDSaudi ArabiaSA
SDNSudanSD
SENSenegalSN
SINGSingaporeSG
SKORRepublic of KoreaKR
SLBSolomon IslandsSB
SPNSpainES
SVKSlovakiaSK
SVNSloveniaSI
SWEDSwedenSE
SWTZSwitzerlandCH
THAIThailandTH
TUNTunisiaTN
TURKTürkiyeTR
UAEUnited Arab EmiratesAE
UGAUgandaUG
UKUnited KingdomGB
UKRUkraineUA
URYUruguayUY
USUnited StatesUS
VATVatican CityVA
VENZVenezuelaVE
VTNMVietnamVN
ZWEZimbabweZW
Intergovernmental6 codes
CodeNameCountry
ABArabsatSA
ESAEuropean Space Agency
ESROEuropean Space Research Organization
EUMEEUMETSAT
ISSInternational Space Station
NATONATO
Agencies1 codes
CodeNameCountry
ISROIndian Space Research OrganisationIN
Organizations13 codes
CodeNameCountry
ABSAsia Broadcast SatelliteBM
ACAsiaSatCN
EUTEEutelsatFR
GLOBGlobalstarUS
IMInmarsatGB
IRIDIridiumUS
ITSOIntelsatUS
NICONew ICOGB
O3BO3b Networks (SES)LU
ORBORBCOMMUS
RASCRascomStar-QAFMU
SEALSea Launch
SESSESLU
Joint programmes10 codes
CodeNameCountry
CHBZChina/BrazilCN
CHTUChina/TürkiyeCN
FGERFrance/GermanyFR
FRITFrance/ItalyFR
GRSAGreece/Saudi ArabiaGR
PRESChina/European Space AgencyCN
SGJPSingapore/JapanSG
STCTSingapore/TaiwanSG
TMMCTurkmenistan/MonacoTM
USBZUnited States/BrazilUS
Unknown / unassigned2 codes
CodeNameCountry
TBDTo be determined
UNKUnknown

136 owner codes mapped.

11

Derived metrics

Every derived value on the site points at one of these definitions. The version changes whenever the rule changes; the inputs list the exact canonical columns the rule reads. None of them is a safety metric.

SatelliteIndex Activity Score

activity_score · v0.1

updated 11 Sept 2026 18:53 UTC

Experimental. 100·(launched_last_30d/active) + 10·(launched_last_365d/active), capped at 100. Measures how fast a constellation is changing; not a safety or quality metric.

Inputs

  • constellation_stats.launched_last_30d
  • constellation_stats.launched_last_365d
  • constellation_stats.active

Constellation membership

constellation_membership · v1.0

updated 11 Sept 2026 18:53 UTC

Membership in a CelesTrak GP group mapped to a constellation first (source-backed); otherwise a documented regular expression on the object name (derived). Membership history is kept in constellation_memberships.

Inputs

  • celestrak groups
  • registry/constellations.yaml

Data freshness

freshness · v1.0

updated 11 Sept 2026 18:53 UTC

fresh < 12 h, aging 12–48 h, stale > 48 h since the source's last successful sync (orbital); catalog thresholds are 36 h / 96 h.

Inputs

  • connectors.last_success_at

Orbit class

orbit_class · v1.0

updated 11 Sept 2026 18:53 UTC

Derived from the latest element set: GEO = period 1436±30 min, e<0.05, i<20°; HEO = e>0.25 and apogee>35 000 km; LEO = apogee<2 000 km; MEO = 2 000 km≤perigee and apogee<35 586+2 000 km; else OTHER.

Inputs

  • orbital_state.period_minutes
  • orbital_state.eccentricity
  • orbital_state.inclination
  • orbital_state.apogee_km
  • orbital_state.perigee_km

Orbital density by altitude bucket

orbital_density · v1.0

updated 11 Sept 2026 18:53 UTC

Count of on-orbit Earth-centred objects per perigee bucket (0–200 … 1000–2000 km, MEO, GEO, HEO). Informational only — not a collision-risk metric.

Inputs

  • satellites.perigee_km
  • satellites.orbit_class

Object status

status · v1.0

updated 11 Sept 2026 18:53 UTC

SATCAT operational status code (+/P → ACTIVE, B/S/X → INACTIVE, D or decay date → DECAYED, ? → UNKNOWN). Objects without a SATCAT code but present in the CelesTrak `active` GP group are ACTIVE; debris and rocket bodies still on orbit are INACTIVE.

Inputs

  • satcat.OPS_STATUS_CODE
  • satcat.DECAY_DATE
  • celestrak.active

12

Freshness thresholds

fresh < 12 h, aging 12–48 h, stale > 48 h since the source's last successful sync (orbital); catalog thresholds are 36 h / 96 h.

Two scales are in use, and both are shown rather than hidden behind an average:

  • Per connector (/status/data, /sources): relative to the connector’s own interval — fresh under 3 × interval, aging under 12 ×, stale beyond; unavailable if it never succeeded, not enabled for planned connectors.
  • Per object (satellite pages): the orbit is fresh under 12 h, aging from 12 to 48 h and stale after 48 h since the element epoch or the last successful orbital sync; catalog metadata uses 36 h / 96 h.

The health endpoint reports the worst connector freshness as the platform’s data status.

13

Limitations

  • Name-pattern classification errors. Constellation membership and mission type inferred from names can misfile objects with unusual or reused names (test payloads, renamed spacecraft, shared bus names). Group-backed memberships are more reliable than pattern-backed ones; both are labelled.
  • Catalog latency. SATCAT status codes, decay dates and new-object entries lag reality by hours to weeks. A satellite can be operational before it is marked +, and decayed objects may stay “on orbit” until the catalog catches up.
  • GEO drift and graveyard objects. Inclined, drifting or super-synchronous objects sit near the GEO/MEO/OTHER boundaries and may switch class between element sets.
  • Analyst objects. Objects tracked without a COSPAR designator (and sometimes with temporary NORAD numbers) have no launch, owner or country and can later be re-identified — that is exactly the case the manual review queue exists for.
  • Element-set age. Positions inherit the age of their elements; a stale feed means every live position on the site is stale, and the status page says so.
  • Coverage. Only CelesTrak feeds are ingested today; government registries (Space-Track, UNOOSA), ESA DISCOS and GCAT are registered as planned sources but contribute nothing yet.

14

Disclaimer

SatelliteIndex.io is an informational platform. Orbital positions, predictions, conjunction information, reentry predictions, and derived metrics may contain delays or uncertainty and must not be used as the sole source for safety-critical, navigation, mission-control, military, or operational decisions.

SatelliteIndex aggregates public and licensed orbital, governmental, scientific, and operator data from multiple sources. Orbital data courtesy of CelesTrak. Derived classifications (constellation membership, orbit class, mission type) follow the published methodology.

See the terms of use. Corrections and questions: about.