Skip to content

CelesTrak Data Source

Respectful Usage

CelesTrak is freely available for public use, but users should be respectful of the service. Avoid excessive automated requests, and take advantage of caching to minimize repeated queries. For large-scale or commercial applications, consider downloading once and distributing data internally.

CelesTrak is the simplest entry point for satellite ephemeris data: it is free, requires no account, and provides frequently updated orbital element sets for thousands of satellites. Maintained by T.S. Kelso since 1985, it is a widely used resource for satellite tracking and space situational awareness.

How It Works

Brahe provides a CelestrakClient that talks to celestrak.org and returns structured records. For GP (General Perturbations) queries the client returns GPRecord objects -- the same type used by the SpaceTrack client, so downstream code works interchangeably with either data source. The client also supports Supplemental GP data from constellation operators (CelestrakQuery.sup_gp) and satellite catalog metadata (CelestrakQuery.satcat).

To minimize load on CelesTrak's servers and improve performance, the client caches downloaded data for 6 hours. Cache files are stored in the system cache directory (~/.cache/brahe/celestrak/) and are keyed by query URL.

Customizing Cache

Pass cache_max_age=0.0 to disable caching, or a custom value in seconds to change the TTL.

Querying Satellite Data

The client offers two levels of API. Compact convenience methods handle the most common lookups -- pass a catalog number, group name, object name, or international designator directly to get_gp or get_satcat. For more control, the CelestrakQuery builder lets you compose queries with filtering, sorting, output format selection, and result limits.

The following example retrieves GP data for a single satellite by NORAD catalog number:

This example demonstrates querying CelesTrak for a satellite's general
perturbations (GP) data using its NORAD catalog number.
"""

import brahe as bh

# Initialize EOP data
bh.initialize_eop()

# Query ISS GP data by NORAD catalog number
client = bh.celestrak.CelestrakClient()
records = client.get_gp(catnr=25544)
record = records[0]

print("ISS GP Data:")
print(f"  Name: {record.object_name}")
print(f"  NORAD ID: {record.norad_cat_id}")
print(f"  Epoch: {record.epoch}")
print(f"  Inclination: {record.inclination:.2f}°")
print(f"  RAAN: {record.ra_of_asc_node:.2f}°")
print(f"  Eccentricity: {record.eccentricity:.6f}")
//! perturbations (GP) data using its NORAD catalog number.
//!
//! FLAGS = ["CI-ONLY"]

#[allow(unused_imports)]
use brahe as bh;
use bh::celestrak::CelestrakClient;

fn main() {
    bh::initialize_eop().unwrap();

    // Query ISS GP data by NORAD catalog number
    let client = CelestrakClient::new();
    let records = client.get_gp_by_catnr(25544).unwrap();
    let record = &records[0];

    println!("ISS GP Data:");
    println!("  Name: {}", record.object_name.as_deref().unwrap_or("Unknown"));
    println!("  NORAD ID: {}", record.norad_cat_id.unwrap_or(0));
    println!("  Epoch: {}", record.epoch.as_deref().unwrap_or("Unknown"));
    println!("  Inclination: {:.2}°", record.inclination.unwrap_or(0.0));
    println!("  RAAN: {:.2}°", record.ra_of_asc_node.unwrap_or(0.0));
    println!("  Eccentricity: {:.6}", record.eccentricity.unwrap_or(0.0));

}
Output
1
2
3
4
5
6
7
ISS GP Data:
  Name: ISS (ZARYA)
  NORAD ID: 25544
  Epoch: 2026-03-22T03:54:40.385952
  Inclination: 51.63°
  RAAN: 10.70°
  Eccentricity: 0.000619
1
2
3
4
5
6
7
ISS GP Data:
  Name: ISS (ZARYA)
  NORAD ID: 25544
  Epoch: 2026-03-22T03:54:40.385952
  Inclination: 51.63°
  RAAN: 10.70°
  Eccentricity: 0.000619

Other common lookup patterns include querying by group name (group="stations"), object name (name="ISS"), or international designator (intdes="1998-067A"). All of these are available as keyword arguments to get_gp or as builder methods on CelestrakQuery.gp.

Client-Side Filtering

CelesTrak's API only supports a few server-side filters (group, catalog number, name, international designator). For more complex filtering, brahe provides client-side operators that use the same syntax as the SpaceTrack query interface. These filters are applied after downloading the full dataset, so they work on any field in the response:

import brahe as bh
from brahe.spacetrack import operators as op

client = bh.celestrak.CelestrakClient()
query = (
    bh.celestrak.CelestrakQuery.gp
    .group("stations")
    .filter("INCLINATION", op.greater_than("50"))
    .filter("OBJECT_TYPE", op.not_equal("DEBRIS"))
    .order_by("INCLINATION", False)
    .limit(10)
)
records = client.query(query)

Satellite Groups

CelesTrak organizes satellites into logical groups accessible via simple names such as stations, starlink, gnss, active, and weather. Groups span several categories including temporal (active, last-30-days), communications (starlink, oneweb, iridium-NEXT), navigation (gnss, gps-ops, galileo), earth observation (weather, planet, earth-resources), and scientific or special purpose (science, analyst, visual). Group names and contents evolve as missions launch, deorbit, or change status.

For a complete listing of available groups, see the CelesTrak API Reference or visit CelesTrak GP Element Sets.


See Also