Skip to content

Common Queries

This page shows practical query patterns for everyday Space-Track tasks: fetching current ephemeris data, filtering the active catalog, and monitoring upcoming decays.

For the query builder API and operator reference, see Query Builder. For executing queries against the API, see Client.

Latest Ephemeris for a Single Object

The most common query retrieves the latest GP record for a specific satellite. Filter by NORAD_CAT_ID, order by EPOCH descending, and limit to 1 to get the most recent element set.

import brahe as bh

# Get the latest GP record for the ISS (NORAD 25544)
# Order by EPOCH descending so the most recent is first, limit to 1
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("NORAD_CAT_ID", "25544")
    .order_by("EPOCH", bh.SortOrder.DESC)
    .limit(1)
)

url_path = query.build()
print(f"Latest GP for ISS:\n  {url_path}")
# Latest GP for ISS:
#   /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/orderby/EPOCH desc/limit/1/format/json

# Get the latest GP for a Starlink satellite (NORAD 48274)
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("NORAD_CAT_ID", "48274")
    .order_by("EPOCH", bh.SortOrder.DESC)
    .limit(1)
)

url_path = query.build()
print(f"\nLatest GP for Starlink-2541:\n  {url_path}")
# Latest GP for Starlink-2541:
#   /basicspacedata/query/class/gp/NORAD_CAT_ID/48274/orderby/EPOCH desc/limit/1/format/json
use brahe as bh;
use bh::spacetrack::{SpaceTrackQuery, RequestClass, SortOrder};

fn main() {
    // Get the latest GP record for the ISS (NORAD 25544)
    // Order by EPOCH descending so the most recent is first, limit to 1
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("NORAD_CAT_ID", "25544")
        .order_by("EPOCH", SortOrder::Desc)
        .limit(1);

    let url_path = query.build();
    println!("Latest GP for ISS:\n  {}", url_path);
    // Latest GP for ISS:
    //   /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/orderby/EPOCH desc/limit/1/format/json

    // Get the latest GP for a Starlink satellite (NORAD 48274)
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("NORAD_CAT_ID", "48274")
        .order_by("EPOCH", SortOrder::Desc)
        .limit(1);

    let url_path = query.build();
    println!("\nLatest GP for Starlink-2541:\n  {}", url_path);
    // Latest GP for Starlink-2541:
    //   /basicspacedata/query/class/gp/NORAD_CAT_ID/48274/orderby/EPOCH desc/limit/1/format/json
}

Latest Ephemeris for Non-Decayed Objects

To query the full active catalog, filter where DECAY_DATE equals null_val(). This excludes objects that have already reentered. Combine with additional filters like OBJECT_TYPE or PERIOD to narrow the results.

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

# Get latest GP for all non-decayed objects
# DECAY_DATE = null-val means the object has not decayed
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("DECAY_DATE", op.null_val())
    .order_by("NORAD_CAT_ID", bh.SortOrder.ASC)
)

url_path = query.build()
print(f"All non-decayed objects:\n  {url_path}")
# All non-decayed objects:
#   /basicspacedata/query/class/gp/DECAY_DATE/null-val/orderby/NORAD_CAT_ID asc/format/json

# Filter to only active payloads (exclude debris and rocket bodies)
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("DECAY_DATE", op.null_val())
    .filter("OBJECT_TYPE", "PAYLOAD")
    .order_by("NORAD_CAT_ID", bh.SortOrder.ASC)
)

url_path = query.build()
print(f"\nActive payloads only:\n  {url_path}")
# Active payloads only:
#   /basicspacedata/query/class/gp/DECAY_DATE/null-val/OBJECT_TYPE/PAYLOAD/orderby/NORAD_CAT_ID asc/format/json

# Filter to active objects in LEO (period under 128 minutes)
query = (
    bh.SpaceTrackQuery(bh.RequestClass.GP)
    .filter("DECAY_DATE", op.null_val())
    .filter("PERIOD", op.less_than("128"))
    .order_by("NORAD_CAT_ID", bh.SortOrder.ASC)
)

url_path = query.build()
print(f"\nActive LEO objects:\n  {url_path}")
# Active LEO objects:
#   /basicspacedata/query/class/gp/DECAY_DATE/null-val/PERIOD/<128/orderby/NORAD_CAT_ID asc/format/json
use brahe as bh;
use bh::spacetrack::{SpaceTrackQuery, RequestClass, SortOrder};
use bh::spacetrack::operators;

fn main() {
    // Get latest GP for all non-decayed objects
    // DECAY_DATE = null-val means the object has not decayed
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("DECAY_DATE", &operators::null_val())
        .order_by("NORAD_CAT_ID", SortOrder::Asc);

    let url_path = query.build();
    println!("All non-decayed objects:\n  {}", url_path);
    // All non-decayed objects:
    //   /basicspacedata/query/class/gp/DECAY_DATE/null-val/orderby/NORAD_CAT_ID asc/format/json

    // Filter to only active payloads (exclude debris and rocket bodies)
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("DECAY_DATE", &operators::null_val())
        .filter("OBJECT_TYPE", "PAYLOAD")
        .order_by("NORAD_CAT_ID", SortOrder::Asc);

    let url_path = query.build();
    println!("\nActive payloads only:\n  {}", url_path);
    // Active payloads only:
    //   /basicspacedata/query/class/gp/DECAY_DATE/null-val/OBJECT_TYPE/PAYLOAD/orderby/NORAD_CAT_ID asc/format/json

    // Filter to active objects in LEO (period under 128 minutes)
    let query = SpaceTrackQuery::new(RequestClass::GP)
        .filter("DECAY_DATE", &operators::null_val())
        .filter("PERIOD", &operators::less_than("128"))
        .order_by("NORAD_CAT_ID", SortOrder::Asc);

    let url_path = query.build();
    println!("\nActive LEO objects:\n  {}", url_path);
    // Active LEO objects:
    //   /basicspacedata/query/class/gp/DECAY_DATE/null-val/PERIOD/<128/orderby/NORAD_CAT_ID asc/format/json
}

Catalog Size

The full non-decayed catalog contains tens of thousands of records. Consider adding OBJECT_TYPE, orbit regime filters, or limit() to keep response sizes manageable.

Objects Decaying Soon

The Decay request class provides reentry predictions and historical decay records. Use inclusive_range with now() and now_offset() to query a time window.

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

# Get objects predicted to decay within the next 30 days
# The Decay request class provides reentry predictions
query = (
    bh.SpaceTrackQuery(bh.RequestClass.DECAY)
    .filter("DECAY_EPOCH", op.inclusive_range(op.now(), op.now_offset(30)))
    .order_by("DECAY_EPOCH", bh.SortOrder.ASC)
)

url_path = query.build()
print(f"Decaying within 30 days:\n  {url_path}")
# Decaying within 30 days:
#   /basicspacedata/query/class/decay/DECAY_EPOCH/now--now+30/orderby/DECAY_EPOCH asc/format/json

# Get recent actual decays from the past 7 days
query = (
    bh.SpaceTrackQuery(bh.RequestClass.DECAY)
    .filter("DECAY_EPOCH", op.inclusive_range(op.now_offset(-7), op.now()))
    .filter("MSG_TYPE", "Decay")
    .order_by("DECAY_EPOCH", bh.SortOrder.DESC)
)

url_path = query.build()
print(f"\nRecent decays (last 7 days):\n  {url_path}")
# Recent decays (last 7 days):
#   /basicspacedata/query/class/decay/DECAY_EPOCH/now-7--now/MSG_TYPE/Decay/orderby/DECAY_EPOCH desc/format/json
use brahe as bh;
use bh::spacetrack::{SpaceTrackQuery, RequestClass, SortOrder};
use bh::spacetrack::operators;

fn main() {
    // Get objects predicted to decay within the next 30 days
    // The Decay request class provides reentry predictions
    let query = SpaceTrackQuery::new(RequestClass::Decay)
        .filter("DECAY_EPOCH", &operators::inclusive_range(operators::now(), operators::now_offset(30)))
        .order_by("DECAY_EPOCH", SortOrder::Asc);

    let url_path = query.build();
    println!("Decaying within 30 days:\n  {}", url_path);
    // Decaying within 30 days:
    //   /basicspacedata/query/class/decay/DECAY_EPOCH/now--now+30/orderby/DECAY_EPOCH asc/format/json

    // Get recent actual decays from the past 7 days
    let query = SpaceTrackQuery::new(RequestClass::Decay)
        .filter("DECAY_EPOCH", &operators::inclusive_range(operators::now_offset(-7), operators::now()))
        .filter("MSG_TYPE", "Decay")
        .order_by("DECAY_EPOCH", SortOrder::Desc);

    let url_path = query.build();
    println!("\nRecent decays (last 7 days):\n  {}", url_path);
    // Recent decays (last 7 days):
    //   /basicspacedata/query/class/decay/DECAY_EPOCH/now-7--now/MSG_TYPE/Decay/orderby/DECAY_EPOCH desc/format/json
}

See Also