- Title: Catalogs Endpoint
- Conformance Classes:
https://api.stacspec.org/v1.0.0/core(required)https://api.stacspec.org/v1.0.0-beta.1/catalogs-endpoint(required)https://api.stacspec.org/v1.0.0-rc.2/children(recommended)
- Scope: STAC API - Core
- Extension Maturity Classification: Proposal
- Dependencies:
- STAC API - Core
- STAC API - Collections
- STAC API - Children
- STAC API - Transaction (Reference pattern)
- Owner: @jonhealy1
This extension enables a Virtual Organizational architecture to enhance discoverability. It adds a dedicated /catalogs endpoint that serves as a machine-readable registry for logical sub-catalogs, allowing users to organize data into flexible, virtual hierarchies (e.g., by theme, semantics, or project) without duplicating the underlying data or altering the standard behavior of the API Root.
In addition to discovery, this extension defines Transactional endpoints to create, update, and delete Catalogs and manage their associations with Collections, effectively acting as a management API for these virtual organizational structures.
In this model, the API supports a Recursive Hierarchical structure:
- Global Root (
/): The standard entry point. It remains a clean STAC Landing Page but includes a link to the Catalogs Registry. - The Registry (
/catalogs): The top-level list of root catalogs (e.g., "Forestry", "Oceanography"). - Sub-Catalogs (
/catalogs/{id}): These behave as standard STAC Catalogs. Unlike the root, they can contain nested Sub-Catalogs (accessible via/catalogs/{id}/catalogs) in addition to Collections, allowing for deep, multi-level organizational trees (e.g.,Provider -> Theme -> Year).
A core tenet of this extension is Data Safety. The /catalogs endpoints are strictly for Organization, while the core /collections endpoints are reserved for Destruction. Operations performed via the catalogs endpoint (like deleting a catalog) are guaranteed to never result in the accidental loss of Collection or Item data.
Note on Dynamic Linking:
To ensure data consistency and reduce storage overhead, implementations SHOULD generate hierarchical links (e.g., rel="child", rel="parent") dynamically at runtime based on the requested endpoint context, rather than persisting static link objects in the database.
| Method | URI | Description |
|---|---|---|
GET |
/catalogs |
The Registry. Lists all available sub-catalogs. |
GET |
/catalogs/{catalogId} |
Sub-Catalog Root. Acts as the Landing Page for the provider. |
GET |
/catalogs/{catalogId}/conformance |
Conformance classes specific to this sub-catalog. |
GET |
/catalogs/{catalogId}/queryables |
Filter Extension. Lists fields available for filtering in this sub-catalog. |
GET |
/catalogs/{catalogId}/children |
Children. Lists all child resources (Catalogs and Collections). Supports filtering via ?type=Catalog or ?type=Collection. |
GET |
/catalogs/{catalogId}/catalogs |
Sub-Catalogs List. Lists only the child catalogs of this catalog (for hierarchy traversal). |
GET |
/catalogs/{catalogId}/collections |
Lists collections belonging to this sub-catalog. |
GET |
/catalogs/{catalogId}/collections/{collectionId} |
Gets a specific collection definition. |
GET |
/catalogs/{catalogId}/collections/{collectionId}/items |
Item Search. Fetches items from this specific collection. |
GET |
/catalogs/{catalogId}/collections/{collectionId}/items/{itemId} |
Gets a single specific item. |
These endpoints allow for the dynamic creation and deletion of the federation structure.
| Method | URI | Description |
|---|---|---|
POST |
/catalogs |
Create Root Catalog. Registers a new top-level catalog. |
DELETE |
/catalogs/{catalogId} |
Disband Catalog. Removes a sub-catalog. Safety: Never deletes linked collections. |
POST |
/catalogs/{catalogId}/catalogs |
Create Sub-Catalog. Creates a new catalog and links it as a child of this catalog. |
DELETE |
/catalogs/{catalogId}/catalogs/{subCatalogId} |
Unlink Sub-Catalog. Removes the link to the sub-catalog. Safety: Does not delete the sub-catalog. |
POST |
/catalogs/{catalogId}/collections |
Create Collection. Creates a collection and links it to this catalog. |
DELETE |
/catalogs/{catalogId}/collections/{collectionId} |
Unlink Collection. Removes the link from the parent catalog. Safety: Never deletes the collection data. |
This extension explicitly supports Poly-hierarchy, allowing a single STAC Collection to belong to multiple Catalogs simultaneously.
Unlike a standard file system where a folder can only live in one path, this architecture allows for logical grouping across different dimensions without duplicating data.
- Example: A
Sentinel-2collection can be linked as a child of theUSGSCatalog (Provider) AND theOptical-DataCatalog (Theme). - Behavior: When accessing a Collection via a specific Catalog endpoint (e.g.,
/catalogs/{id}/collections/{col_id}), the API SHOULD preserve the navigation context by generating arel="parent"link pointing back to that specific Catalog.
Implementations supporting the Transaction endpoints MUST adhere to the following behaviors:
- Body: Accepts a standard STAC Catalog JSON object.
- Behavior: The API creates the Catalog resource and makes it available in the
/catalogsregistry list.
- Body: Accepts a standard STAC Catalog JSON object.
- Behavior:
- Creates the new Catalog resource.
- Automatic Linking: Automatically registers the new Catalog as a child of
{id}. - Reverse Linking: Automatically adds a
rel="child"link in the parent Catalog{id}pointing to the new sub-catalog. - Result: The new catalog is discoverable via
GET /catalogs/{id}/catalogsAND via the global registryGET /catalogs(unless explicitly hidden).
- Behavior (Disband):
- The Catalog object
{id}is deleted from the database. - All Child Collections AND Child Sub-Catalogs linked to this catalog are Unlinked.
- Adoption: If an unlinked child (Collection or Catalog) has no other parents, it MUST be automatically adopted by the Root Catalog to ensure data/structure is preserved.
- Constraint: This operation MUST NOT delete Collection or Item data.
- The Catalog object
- Behavior (Unlink):
- The Sub-Catalog
{subId}is Unlinked from the parent Catalog{id}. - Safety: The Sub-Catalog resource itself is NOT deleted.
- Adoption: If the Sub-Catalog has no other parents (orphaned), it MUST be automatically adopted by the Root Catalog to ensure it remains discoverable.
- Constraint: This operation only removes the specific hierarchical link between
{id}and{subId}.
- The Sub-Catalog
- Body: Accepts a standard STAC Collection JSON object.
- Behavior:
- Creates the Collection resource (or updates links if it exists).
- Automatic Linking: Automatically registers the Collection as a child of
{catalogId}. - Reverse Linking: Automatically adds a
rel="child"link in the Catalog pointing to the new Collection.
- Behavior (Unlink):
- The Collection is Unlinked from the specific catalog
{catalogId}. - If the Collection belongs to other catalogs, those links remain.
- If the Collection belongs only to this catalog, it becomes an orphan and MUST be automatically adopted by the Root Catalog.
- Constraint: This operation MUST NOT delete Collection or Item data. To delete data, the client must use the core
/collections/{id}endpoint.
- The Collection is Unlinked from the specific catalog
Proper linking is critical for clients to navigate the federation structure.
This is the entry point.
rel="catalogs": MUST point to the/catalogsendpoint (the registry).rel="service-desc": Points to the OpenAPI definition.
This resource acts as the Landing Page for the provider.
rel="self": MUST point to/catalogs/{catalogId}.rel="parent": MUST point to the Global Root (/).rel="root": SHOULD point to the Global Root (/) to maintain a single navigation tree.rel="data": MUST point to/catalogs/{catalogId}/collections.rel="children": MUST point to/catalogs/{catalogId}/children(if Children extension is implemented).
This resource, and all of its sub-resources, represents a Collection within the context of a specific Catalog.
rel="alternate": MAY be provided to point to the corresponding/collections/{collectionId}/*endpoints, and vice versa.
Note
All sub-resources can be considered, accordingly to other STAC API extensions that are implemented.
For example, if the Filter extension
is implemented and supports Queryables,
then rel="alternate" links MAY be included in corresponding responses as well:
/catalogs/{catalogId}/collections/{collectionId}/queryables/collections/{collectionId}/queryables/queryables?collections={collectionId}
Note
The rel="alternate" link is optional to allow implementation omitting the reference if such endpoint should be protected
and hidden from clients. Otherwise, it is RECOMMENDED to provide this link for better interoperability and discoverability
of clients that are typically aware of the core STAC API structure.
This endpoint returns a JSON object structurally similar to a standard /collections response, but it contains a list of Catalog objects in a catalogs array.
{
"catalogs": [
{
"id": "usgs-landsat",
"type": "Catalog",
"title": "USGS Landsat",
"description": "Landsat collections provided by USGS.",
"stac_version": "1.0.0",
"links": [
{ "rel": "self", "href": "https://api.example.com/catalogs/usgs-landsat" },
{ "rel": "root", "href": "https://api.example.com/" },
{ "rel": "child", "href": "https://api.example.com/catalogs/usgs-landsat/collections" }
]
},
{
"id": "esa-sentinel",
"type": "Catalog",
"title": "ESA Sentinel",
"description": "Sentinel collections provided by ESA.",
"stac_version": "1.0.0",
"links": [
{ "rel": "self", "href": "https://api.example.com/catalogs/esa-sentinel" },
{ "rel": "root", "href": "https://api.example.com/" },
{ "rel": "child", "href": "https://api.example.com/catalogs/esa-sentinel/collections" }
]
}
],
"links": [
{
"rel": "self",
"href": "https://api.example.com/catalogs"
},
{
"rel": "root",
"href": "https://api.example.com/"
}
]
}The global root remains a standard STAC Landing Page. Note the addition of the rel="catalogs" link.
{
"stac_version": "1.0.0",
"type": "Catalog",
"id": "stac-api",
"title": "Standard STAC API with Federation",
"description": "A standard STAC API that also supports federated catalogs.",
"conformsTo": [
"https://api.stacspec.org/v1.0.0/core",
"https://api.stacspec.org/v1.0.0-beta.1/catalogs-endpoint"
],
"links": [
{
"rel": "self",
"type": "application/json",
"href": "https://api.example.com/"
},
{
"rel": "service-desc",
"type": "application/vnd.oai.openapi+json;version=3.0",
"href": "https://api.example.com/api"
},
{
"rel": "data",
"type": "application/json",
"href": "https://api.example.com/collections",
"title": "Global Collections List"
},
{
"rel": "catalogs",
"type": "application/json",
"href": "https://api.example.com/catalogs",
"title": "Federated Catalogs Registry"
}
]
}This endpoint returns a list of both child Catalogs and child Collections.
{
"children": [
{
"id": "sub-catalog-1",
"type": "Catalog",
"title": "A nested sub-catalog",
"links": [
{ "rel": "self", "href": "https://api.example.com/catalogs/sub-catalog-1" }
]
},
{
"id": "collection-1",
"type": "Collection",
"title": "A child collection",
"links": [
{ "rel": "self", "href": "https://api.example.com/collections/collection-1" }
]
}
],
"links": [
{
"rel": "self",
"href": "https://api.example.com/catalogs/c1/children"
},
{
"rel": "next",
"href": "https://api.example.com/catalogs/c1/children?token=..."
}
]
}This extension reserves the path /catalogs/{catalogId}/queryables to support the STAC Filter Extension within a sub-catalog context.
However, implementation of this endpoint is OPTIONAL.
- A sub-catalog MUST only expose this endpoint if it advertises conformance to the Filter Extension URI (e.g.,
https://api.stacspec.org/v1.0.0-rc.2/filter) in the Sub-Catalog Landing Page (/catalogs/{catalogId}). - If implemented, the queryables response must be scoped specifically to that sub-catalog.