SpaceTrackQuery provides a fluent builder API for constructing Space-Track.org API queries. Each builder method returns a new query instance, allowing method chaining. Call build() to produce the URL path string that the client appends to the base URL.
Create a query by specifying the request class. The default controller is selected automatically based on the class -- GP and SATCAT use BasicSpaceData, while CDMPublic uses ExpandedSpaceData. Add filters with the filter() method using Space-Track field names.
importbraheasbh# Build a GP query for the ISS by NORAD catalog IDquery=bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544")url_path=query.build()print(f"GP query URL path:\n{url_path}")# GP query URL path:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/json# Build a SATCAT query for US-owned objectsquery=bh.SpaceTrackQuery(bh.RequestClass.SATCAT).filter("COUNTRY","US")url_path=query.build()print(f"\nSATCAT query URL path:\n{url_path}")# SATCAT query URL path:# /basicspacedata/query/class/satcat/COUNTRY/US/format/json# The default controller is inferred from the request classquery=bh.SpaceTrackQuery(bh.RequestClass.CDM_PUBLIC)url_path=query.build()print(f"\nCDM query URL path (uses expandedspacedata controller):\n{url_path}")# CDM query URL path (uses expandedspacedata controller):# /expandedspacedata/query/class/cdm_public/format/json
usebraheasbh;usebh::spacetrack::{SpaceTrackQuery,RequestClass};fnmain(){// Build a GP query for the ISS by NORAD catalog IDletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544");leturl_path=query.build();println!("GP query URL path:\n {}",url_path);// GP query URL path:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/json// Build a SATCAT query for US-owned objectsletquery=SpaceTrackQuery::new(RequestClass::SATCAT).filter("COUNTRY","US");leturl_path=query.build();println!("\nSATCAT query URL path:\n {}",url_path);// SATCAT query URL path:// /basicspacedata/query/class/satcat/COUNTRY/US/format/json// The default controller is inferred from the request classletquery=SpaceTrackQuery::new(RequestClass::CDMPublic);leturl_path=query.build();println!("\nCDM query URL path (uses expandedspacedata controller):\n {}",url_path);// CDM query URL path (uses expandedspacedata controller):// /expandedspacedata/query/class/cdm_public/format/json}
The operators module provides functions that generate operator-prefixed strings for filter values. These compose naturally -- greater_than(now_offset(-7)) nests the time offset inside the comparison operator.
importbraheasbhfrombrahe.spacetrackimportoperatorsasop# Filter by NORAD ID range using inclusive_rangequery=bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID",op.inclusive_range("25544","25600"))print(f"Range filter:\n{query.build()}")# Range filter:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544--25600/format/json# Filter for objects with low eccentricity using less_thanquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("ECCENTRICITY",op.less_than("0.01")).filter("OBJECT_TYPE","PAYLOAD"))print(f"\nMultiple filters:\n{query.build()}")# Multiple filters:# /basicspacedata/query/class/gp/ECCENTRICITY/<0.01/OBJECT_TYPE/PAYLOAD/format/json# Filter for recently launched objects using greater_than + now_offsetquery=bh.SpaceTrackQuery(bh.RequestClass.SATCAT).filter("LAUNCH",op.greater_than(op.now_offset(-30)))print(f"\nRecent launches (last 30 days):\n{query.build()}")# Recent launches (last 30 days):# /basicspacedata/query/class/satcat/LAUNCH/>now-30/format/json# Search by name pattern using likequery=bh.SpaceTrackQuery(bh.RequestClass.SATCAT).filter("SATNAME",op.like("STARLINK"))print(f"\nName pattern match:\n{query.build()}")# Name pattern match:# /basicspacedata/query/class/satcat/SATNAME/~~STARLINK/format/json# Filter for multiple NORAD IDs using or_listquery=bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID",op.or_list(["25544","48274","54216"]))print(f"\nMultiple IDs:\n{query.build()}")# Multiple IDs:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544,48274,54216/format/json
usebraheasbh;usebh::spacetrack::{SpaceTrackQuery,RequestClass};usebh::spacetrack::operators;fnmain(){// Filter by NORAD ID range using inclusive_rangeletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID",&operators::inclusive_range("25544","25600"));println!("Range filter:\n {}",query.build());// Range filter:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544--25600/format/json// Filter for objects with low eccentricity using less_thanletquery=SpaceTrackQuery::new(RequestClass::GP).filter("ECCENTRICITY",&operators::less_than("0.01")).filter("OBJECT_TYPE","PAYLOAD");println!("\nMultiple filters:\n {}",query.build());// Multiple filters:// /basicspacedata/query/class/gp/ECCENTRICITY/<0.01/OBJECT_TYPE/PAYLOAD/format/json// Filter for recently launched objects using greater_than + now_offsetletquery=SpaceTrackQuery::new(RequestClass::SATCAT).filter("LAUNCH",&operators::greater_than(operators::now_offset(-30)));println!("\nRecent launches (last 30 days):\n {}",query.build());// Recent launches (last 30 days):// /basicspacedata/query/class/satcat/LAUNCH/>now-30/format/json// Search by name pattern using likeletquery=SpaceTrackQuery::new(RequestClass::SATCAT).filter("SATNAME",&operators::like("STARLINK"));println!("\nName pattern match:\n {}",query.build());// Name pattern match:// /basicspacedata/query/class/satcat/SATNAME/~~STARLINK/format/json// Filter for multiple NORAD IDs using or_listletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID",&operators::or_list(&["25544","48274","54216"]));println!("\nMultiple IDs:\n {}",query.build());// Multiple IDs:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544,48274,54216/format/json}
Operator Composition
Operators are string-generating functions. You can compose them by nesting:
greater_than(now_offset(-7)) produces ">now-7" (epoch after 7 days ago)
inclusive_range(now_offset(-30), now()) produces "now-30--now" (within last 30 days)
Control result ordering, pagination, and field selection. Multiple order_by calls are cumulative -- results are sorted by the first field, then by subsequent fields for ties.
importbraheasbh# Order results by epoch descending and limit to 5 recordsquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544").order_by("EPOCH",bh.SortOrder.DESC).limit(5))print(f"Ordered and limited:\n{query.build()}")# Ordered and limited:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/orderby/EPOCH desc/limit/5/format/json# Use limit with offset for paginationquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("OBJECT_TYPE","PAYLOAD").order_by("NORAD_CAT_ID",bh.SortOrder.ASC).limit_offset(10,20))print(f"\nPaginated results:\n{query.build()}")# Paginated results:# /basicspacedata/query/class/gp/OBJECT_TYPE/PAYLOAD/orderby/NORAD_CAT_ID asc/limit/10,20/format/json# Select specific fields with predicates_filterquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544").predicates_filter(["OBJECT_NAME","EPOCH","INCLINATION","PERIOD"]))print(f"\nFiltered fields:\n{query.build()}")# Filtered fields:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/predicates/OBJECT_NAME,EPOCH,INCLINATION,PERIOD/format/json# Enable metadata and distinct resultsquery=(bh.SpaceTrackQuery(bh.RequestClass.SATCAT).filter("COUNTRY","US").distinct(True).metadata(True))print(f"\nDistinct with metadata:\n{query.build()}")# Distinct with metadata:# /basicspacedata/query/class/satcat/COUNTRY/US/metadata/true/distinct/true/format/json
usebraheasbh;usebh::spacetrack::{SpaceTrackQuery,RequestClass,SortOrder};fnmain(){// Order results by epoch descending and limit to 5 recordsletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544").order_by("EPOCH",SortOrder::Desc).limit(5);println!("Ordered and limited:\n {}",query.build());// Ordered and limited:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/orderby/EPOCH desc/limit/5/format/json// Use limit with offset for paginationletquery=SpaceTrackQuery::new(RequestClass::GP).filter("OBJECT_TYPE","PAYLOAD").order_by("NORAD_CAT_ID",SortOrder::Asc).limit_offset(10,20);println!("\nPaginated results:\n {}",query.build());// Paginated results:// /basicspacedata/query/class/gp/OBJECT_TYPE/PAYLOAD/orderby/NORAD_CAT_ID asc/limit/10,20/format/json// Select specific fields with predicates_filterletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544").predicates_filter(&["OBJECT_NAME","EPOCH","INCLINATION","PERIOD"]);println!("\nFiltered fields:\n {}",query.build());// Filtered fields:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/predicates/OBJECT_NAME,EPOCH,INCLINATION,PERIOD/format/json// Enable metadata and distinct resultsletquery=SpaceTrackQuery::new(RequestClass::SATCAT).filter("COUNTRY","US").distinct(true).metadata(true);println!("\nDistinct with metadata:\n {}",query.build());// Distinct with metadata:// /basicspacedata/query/class/satcat/COUNTRY/US/metadata/true/distinct/true/format/json}
The default output format is JSON, which works with query_json(), query_gp(), and query_satcat(). Other formats like TLE, CSV, and KVN are useful with query_raw() for direct text output.
importbraheasbh# Default format is JSONquery=bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544")print(f"Default (JSON):\n{query.build()}")# Default (JSON):# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/json# Request TLE format for direct TLE text outputquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544").format(bh.OutputFormat.TLE))print(f"\nTLE format:\n{query.build()}")# TLE format:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/tle# Request CSV format for spreadsheet-compatible outputquery=(bh.SpaceTrackQuery(bh.RequestClass.SATCAT).filter("COUNTRY","US").limit(10).format(bh.OutputFormat.CSV))print(f"\nCSV format:\n{query.build()}")# CSV format:# /basicspacedata/query/class/satcat/COUNTRY/US/limit/10/format/csv# Request KVN (CCSDS Keyword-Value Notation) formatquery=(bh.SpaceTrackQuery(bh.RequestClass.GP).filter("NORAD_CAT_ID","25544").format(bh.OutputFormat.KVN))print(f"\nKVN format:\n{query.build()}")# KVN format:# /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/kvn
usebraheasbh;usebh::spacetrack::{SpaceTrackQuery,RequestClass,OutputFormat};fnmain(){// Default format is JSONletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544");println!("Default (JSON):\n {}",query.build());// Default (JSON):// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/json// Request TLE format for direct TLE text outputletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544").format(OutputFormat::TLE);println!("\nTLE format:\n {}",query.build());// TLE format:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/tle// Request CSV format for spreadsheet-compatible outputletquery=SpaceTrackQuery::new(RequestClass::SATCAT).filter("COUNTRY","US").limit(10).format(OutputFormat::CSV);println!("\nCSV format:\n {}",query.build());// CSV format:// /basicspacedata/query/class/satcat/COUNTRY/US/limit/10/format/csv// Request KVN (CCSDS Keyword-Value Notation) formatletquery=SpaceTrackQuery::new(RequestClass::GP).filter("NORAD_CAT_ID","25544").format(OutputFormat::KVN);println!("\nKVN format:\n {}",query.build());// KVN format:// /basicspacedata/query/class/gp/NORAD_CAT_ID/25544/format/kvn}
Format and Query Method Compatibility
The typed query methods (query_gp(), query_satcat(), query_json()) require JSON format. If you set a non-JSON format, use query_raw() to get the raw response string.