Many catalogs. One search.
Search across STAC catalogs through one interface, with Python, Rust, or the command line.
Query Element84, Microsoft Planetary Computer, and others through one API. Items come back deduplicated, with their collection IDs and asset keys normalized to canonical names — regardless of which catalog they came from.
Status: alpha. APIs and YAML schema are not yet stable. Pre-1.0; expect breaking changes.
What’s new in v0.3 · Try GeoParquet in Colab · Local search benchmark
- Federated search: Query multiple STAC catalogs concurrently with spatial, temporal, collection, and item filters.
- Reusable satellite-data inventories: Save metadata for your area of interest and explore it repeatedly without querying every provider again. Fall back to live catalogs when saved coverage is missing or stale.
- Collection discovery: Find available collections and the catalogs that serve them.
- Consistent names: Map provider-specific collection IDs and asset keys to canonical names through configurable aliases.
- Deduplicated results: Merge items across catalogs by item ID, with source provenance available in Rust and CLI results.
- Resilient requests: Configure retries, per-catalog timeouts, and concurrency limits, with per-catalog failure reporting.
- Python, Rust, and CLI: Use synchronous or asynchronous Python clients, embed the Rust engine, or search from the command line.
A single STAC catalog isn't always enough:
- The collection you need lives somewhere else.
- The catalog you usually use is down or rate-limited.
- Different providers index the same scenes under different names.
SuperSTAC queries every catalog you've registered, drops the ones that don't serve the requested collection, runs the rest concurrently with retry and timeouts, then merges and dedupes the results.
Read the SuperSTAC documentation for installation, tutorials, and API guides.
Try the Python quickstart notebook for a two-catalog search, footprint map, and GeoJSON export in Colab or Jupyter.
Add the crates you need:
cargo add superstac-core
cargo add superstac-search
cargo add superstac-engine
cargo add superstac-cli
cargo add superstac-config
cargo add superstac-geoparquetgit clone https://github.com/spatialnode/superstac
cd superstac
cargo build --releaseDrop a superstac.yml next to where you run the binary:
catalogs:
- id: earth-search
url: https://earth-search.aws.element84.com/v1
- id: microsoft
url: https://planetarycomputer.microsoft.com/api/stac/v1Then:
# what collections does each catalog serve?
superstac collections
# search across all of them
superstac search -c sentinel-2-l2a -b 6.0,49.0,7.0,50.0 -d 2024-01-01/2024-01-31 -l 50
# pipe to jq
superstac --json search -c landsat-c2-l2 -l 10 | jq '.metadata'
# inspect a single collection
superstac collections microsoft sentinel-2-l2aRun superstac --help for the full surface. For saved metadata inventories, build
with --features geoparquet and follow the GeoParquet guide.
Published Python wheels include this backend.
Only id and url are required per catalog. Common optional fields:
catalogs:
- id: cdse
url: catalog-url
# Only needed when the catalog uses non-canonical names.
collection_aliases:
sentinel-2-l2a: S2MSI2A
asset_aliases:
sentinel-2-l2a:
blue: B02
green: B03
red: B04
settings:
health_check_strategy: "15m"
deduplicate_items: true
unify_response: true
max_concurrent_catalogs: 8
per_catalog_timeout_seconds: 30
max_retry_attempts: 2The full schema and every setting is documented inline at
crates/core/src/models/settings.rs.
The CLI is a thin wrapper over [superstac-engine]. To embed in your own
binary:
use superstac_config::init_from_yaml;
use superstac_core::models::storage::Storage;
use superstac_engine::SuperSTACEngine;
use superstac_search::query::SearchQuery;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = init_from_yaml(Storage::Memory, "superstac.yml")?;
let engine = SuperSTACEngine::new(db);
engine.start().await?;
let response = engine
.search(SearchQuery {
collections: vec!["sentinel-2-l2a".to_string()],
limit: Some(20),
bbox: None,
datetime: None,
ids: None,
intersects: None,
sortby: None,
})
.await?;
println!("found {} items", response.metadata.total_items);
Ok(())
}| Crate | Purpose |
|---|---|
superstac-core |
domain models, errors, storage trait |
superstac-config |
YAML config loading |
superstac-search |
federated search logic |
superstac-geoparquet |
Reusable satellite-data inventories for repeated searches |
superstac-engine |
runtime (health, introspection, search orchestration) |
superstac-cli |
the superstac binary |
Include superstac --version or Python’s superstac.__version__ in bug reports.
Search diagnostics also include metadata.superstac_version. Provider requests
identify the library as superstac/<version> through the User-Agent header.
New ingested and compacted Parquet files record the writer version in their footer.
Logs flow through tracing. The default level comes from settings.log_level
in your config; override at runtime:
superstac -v search -c sentinel-2-l2a # debug
superstac -q search -c sentinel-2-l2a # warn only
RUST_LOG=superstac_search=debug superstac search -c sentinel-2-l2aSee ROADMAP.MD for short-term, near-term, and long-term priorities, plus the v1.0 release checklist.
MIT. See LICENSE.
Feedback and issues welcome — this is early. If you try it and you see any bug, feel free to open an issue!