Skip to content

Satellite Data Sources

For many modeling tasks it is useful to access satellite ephemeris (orbit) data. This data is made available by a number of sources, including public sources such as Celestrak and Space-Track. Brahe provides functions for accessing satellite data from both of these sources, as well as initializing SGP4 propagators from data.

Both clients have integrated, default rate-limiting and caching to ensure efficient and responsible access to the data. For more information on the configuration of the clients, see the respective language API documentation.

Moving Beyond TLEs

While TLEs have been historically used for satellite ephemeris data, we will soon encounter the problem of catalog number exhaustion. Brahe supports both alpha-5 and GP Record formats that are being adopted to address the issue.

Celestrak

The celestrack client

import brahe as bh
import numpy as np

# Initialize EOP
bh.initialize_eop()

# Get the latest TLE for the ISS (NORAD ID 25544) from Celestrak
client = bh.celestrak.CelestrakClient()
propagator = client.get_sgp_propagator(catnr=25544, step_size=60.0)

# Configure propagation window
epoch_start = propagator.current_epoch()
epoch_end = epoch_start + 7.0 * 86400.0

# Step propagator forward by 1 hour
propagator.propagate_to(epoch_end)

# Get final epoch and state
final_epoch = propagator.current_epoch()
final_state = propagator.current_state()
print(f"Initial epoch: {epoch_start}")
print(f"Final epoch:   {final_epoch}")
print(
    f"Position (km): [{final_state[0] / 1e3:.3f}, {final_state[1] / 1e3:.3f}, {final_state[2] / 1e3:.3f}]"
)
print(
    f"Velocity (m/s): [{final_state[3]:.3f}, {final_state[4]:.3f}, {final_state[5]:.3f}]"
)
use brahe as bh;
use brahe::traits::SStatePropagator;

fn main() {
    // Initialize EOP
    bh::initialize_eop().unwrap();

    // Get the latest TLE for the ISS (NORAD ID 25544) from Celestrak
    let client = bh::celestrak::CelestrakClient::new();
    let mut propagator = client.get_sgp_propagator_by_catnr(25544, 60.0).unwrap();

    // Configure propagation window
    let epoch_start = propagator.current_epoch();
    let epoch_end = epoch_start + 7.0 * 86400.0;  

    // Step propagator forward by 1 hour
    propagator.propagate_to(epoch_end);

    // Get final epoch and state
    let final_epoch = propagator.current_epoch();
    let final_state = propagator.current_state();
    println!("Initial epoch: {}", epoch_start);
    println!("Final epoch:   {}", final_epoch);
    println!(
        "Position (km): [{:.3}, {:.3}, {:.3}]",
        final_state[0] / 1e3,
        final_state[1] / 1e3,
        final_state[2] / 1e3
    );
    println!(
        "Velocity (m/s): [{:.3}, {:.3}, {:.3}]",
        final_state[3],
        final_state[4],
        final_state[5]
    );
}
Output
1
2
3
4
Initial epoch: 2026-06-16 20:48:26.492 UTC
Final epoch:   2026-06-23 20:48:26.492 UTC
Position (km): [-267.314, 6739.694, -827.145]
Velocity (m/s): [-4773.048, -912.504, -5924.949]
1
2
3
4
Initial epoch: 2026-06-16 20:48:26.492 UTC
Final epoch:   2026-06-23 20:48:26.492 UTC
Position (km): [-267.314, 6739.694, -827.145]
Velocity (m/s): [-4773.048, -912.504, -5924.949]

Space-Track

The space-track client requires a user account to access the data. Once authenticated, the client provides access to a variety of satellite data, including TLEs, GP Records, and other records.

import brahe as bh
import os

# Initialize EOP
bh.initialize_eop()

# Authenticate with Space-Track using account credentials
client = bh.spacetrack.SpaceTrackClient(
    os.environ["SPACETRACK_USERNAME"], os.environ["SPACETRACK_PASSWORD"]
)

# Query the latest GP record for the ISS (NORAD ID 25544)
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("NORAD_CAT_ID", "25544")
    .order_by("EPOCH", bh.SortOrder.DESC)
    .limit(1)
)
records = client.query_gp(query)

# Create an SGP4 propagator from the GP record
propagator = records[0].to_sgp_propagator(step_size=60.0)

# Configure propagation window
epoch_start = propagator.current_epoch()
epoch_end = epoch_start + 7.0 * 86400.0

# Propagate forward 7 days
propagator.propagate_to(epoch_end)

# Get final epoch and state
final_epoch = propagator.current_epoch()
final_state = propagator.current_state()
print(f"Initial epoch: {epoch_start}")
print(f"Final epoch:   {final_epoch}")
print(
    f"Position (km): [{final_state[0] / 1e3:.3f}, {final_state[1] / 1e3:.3f}, {final_state[2] / 1e3:.3f}]"
)
print(
    f"Velocity (m/s): [{final_state[3]:.3f}, {final_state[4]:.3f}, {final_state[5]:.3f}]"
)
use brahe as bh;
use bh::spacetrack::{RequestClass, SortOrder, SpaceTrackClient, SpaceTrackQuery};
use brahe::traits::SStatePropagator;

fn main() {
    // Initialize EOP
    bh::initialize_eop().unwrap();

    // Authenticate with Space-Track using account credentials
    let username = std::env::var("SPACETRACK_USERNAME").unwrap();
    let password = std::env::var("SPACETRACK_PASSWORD").unwrap();
    let client = SpaceTrackClient::new(&username, &password);

    // Query the latest GP record for the ISS (NORAD ID 25544)
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("NORAD_CAT_ID", "25544")
        .order_by("EPOCH", SortOrder::Desc)
        .limit(1);
    let records = client.query_gp(&query).unwrap();

    // Create an SGP4 propagator from the GP record
    let mut propagator = bh::SGPPropagator::from_gp_record(&records[0], 60.0).unwrap();

    // Configure propagation window
    let epoch_start = propagator.current_epoch();
    let epoch_end = epoch_start + 7.0 * 86400.0;

    // Propagate forward 7 days
    propagator.propagate_to(epoch_end);

    // Get final epoch and state
    let final_epoch = propagator.current_epoch();
    let final_state = propagator.current_state();
    println!("Initial epoch: {}", epoch_start);
    println!("Final epoch:   {}", final_epoch);
    println!(
        "Position (km): [{:.3}, {:.3}, {:.3}]",
        final_state[0] / 1e3,
        final_state[1] / 1e3,
        final_state[2] / 1e3
    );
    println!(
        "Velocity (m/s): [{:.3}, {:.3}, {:.3}]",
        final_state[3],
        final_state[4],
        final_state[5]
    );
}
Output
1
2
3
4
Initial epoch: 2026-06-09 18:30:49.921 UTC
Final epoch:   2026-06-16 18:30:49.921 UTC
Position (km): [-4582.532, 4686.441, -1786.235]
Velocity (m/s): [-2461.644, -4551.849, -5652.779]
1
2
3
4
Initial epoch: 2026-06-09 18:30:49.921 UTC
Final epoch:   2026-06-16 18:30:49.921 UTC
Position (km): [-4582.532, 4686.441, -1786.235]
Velocity (m/s): [-2461.644, -4551.849, -5652.779]