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.
- Federated search: Query multiple STAC catalogs concurrently with spatial, temporal, collection, and item filters.
- 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-configgit 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.
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-engine |
runtime (health, introspection, search orchestration) |
superstac-cli |
the superstac binary |
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!