SpatioTemporal Asset Catalogs (STAC)
STAC provides a common standard for organising and displaying geospatial information that is simple and lightweight. Any asset that captures information of the Earth in both time and geospatial extents can be considered a spatio-temporal asset.
This page describes the STAC entities used in DataCosmos and includes code examples for common catalog operations.
NOTE
The Python examples on this page require the requests library.
Catalog
A Catalog is a top-level object that logically groups together other Catalogs, Collections and Items. It contains an array of Link objects, each of which links to another resource, typically another Catalog or Collection.
- id - Unique identifier used when querying for Items in this Collection.
- title - Title of the Collection: e.g. "Mantis L1D Data Products".
- description - A human readable description of the Collection.
- links - List of objects containing URLs to other related STAC objects.
- href - A URL link to the corresponding object.
- rel - Relationship between the current and linked documents can be either self, root, parent, child or Item.
- type - Specifies the content-type of the linked object.
- title - Human readable title that can be rendered in displays of the link.
Collection
The STAC Collection specification defines a set of common fields to describe a group of Items that share properties and metadata, and is represented in a JSON format. More information on the required and optional fields of the Collection can be found in the STAC specification.
DataCosmos Collections use the following fields with corresponding descriptions of their purpose.
- id - Unique identifier used when querying for Items in this Collection.
- title - Title of the Collection: e.g. "Mantis L1D Data Products".
- description - A human readable description of the Collection.
- license - A string that identifies the applicable license for the Collection and data contained within it. This will contain the DataCosmos EULA.
- providers - A list of providers that includes the organisations responsible for capturing, processing and hosting the data in a chronological order.
- extent
- spatial - The spatial range in latitude and longitude that the Collection covers. This value is updated over time as new Items are assigned to the Collection.
- temporal - The temporal range specifying the time window the Collection covers. This value is updated over time as new Items are assigned to the Collection.
- summaries - A mapping of key:value summaries where the value can be either a string, range or JSON object.
- platform - List of strings specifying the satellite platform the data product is captured from.
- instrument - List of strings specifying the payload instruments used to capture the data products.
- gsd - The minimum and maximum GSD of the data products.
- eo:bands - Defined as part of the EO extension
- name - Name of the corresponding band in the Collection's Items.
- common_name - Name commonly used to refer to the band from an accepted list of names to allow for searching across instruments.
- description - Description of the corresponding band.
- center_wavelength - The center wavelength of the band in micrometers.
- links - List of objects containing URLs to other related STAC objects.
- item_assets - List of asset objects that match the assets contained within each Item of the Collection. This is used to predetermine the keys of the assets before searching the Collection. Defined as part of the Item Assets extension.
Item
A STAC Item is an augmented GeoJSON Feature object that contains additional fields as part of the STAC specification. These additional fields provide more information on the data contained within the Item and can be used for filtering during searches. The STAC Item inherits the id, type, bbox, geometry and properties fields from the GeoJSON standard. More information on the specification and fields used in the Item definition can be found in the STAC Item specification
- id - Unique ID corresponding to the Item.
- geometry - GeoJSON object that describes the footprint of the Item. Coordinates specified in longitude and latitude. This geometry object is used when searching for data products within a specified geographical region. Formatted according to RFC 7946.
- bounding box - Bounding box of the Item, formatted according to RFC 7946.
- collection - ID of the Collection the Item belongs to.
- properties - Dictionary of additional metadata
- datetime - The acquisition time of the image. Field used when searching for data products within a specified time range.
- created - Timestamp for when the data product was created in the database.
- updated - Timestamp for when the data product was created in the database.
- platform - String specifying the satellite platform the data product is captured from.
- instruments - List of strings specifying the payload instruments used to capture the data products.
- gsd - The GSD of the data product.
- view:off_nadir - Angle between nadir and the pointing of the sensor.
- view:incidence_angle - Angle between the normal to the intercepting surfaces and line of sight to the sensor from the scene center.
- view:azimuth - Angle measured from the sub-satellite point between the scene center and true north.
- view:sun_azimuth - Angle from true north at the scene center to the center point of the sun.
- view:sun_elevation - Angle from the tangent of the scene center point to the sun.
- eo:cloud_cover - The percentage of cloud coverage in the data products. Added as part of the STAC EO extension.
- opencosmos:price - The price of the data product for the authenticated user. This value is dynamically computed on each request and reflects the terms of the user's contract. See the note on pricing below.
- opencosmos:price_currency - The currency of the price (e.g.
GBP,USD). - opencosmos:high_resolution_read_permission - A boolean indicating whether the authenticated user has access to the high-resolution assets of this item.
- opencosmos:data_area_km2 - The area of the data product footprint in square kilometres.
- assets - Contain a list of objects that describe each of the associated assets with the data product such as the image data and metadata files.
- title - Title of the asset.
- description - Human readable description of what the asset contains.
- href - Contains a URL to the asset location.
- type - Contains the content-type of the asset to enable end user applications to automatically read the source data.
- roles - Defined by the STAC specification, roles are used to describe the purpose of each asset. More information can be found in the Item specification.
- links - List of objects containing URLs to other related STAC objects.
Extensions
There are several extensions which have been proposed and added to the STAC specification. In order to make the DataCosmos STAC database easier to navigate and richer with information we have adopted the following extensions as standard.
- View Geometry - Adds metadata related to angles of sensors and other radiance angles that affect the view of resulting data.
- Electro-Optical - Adds metadata relating to the EO data bands and cloud coverage.
- Item Assets - Adds common Item assets to the Collection to provide a human readable and programmatic way of determining assets available in the Collection's Items.
- Query - Enables property-based filtering of Items during searches using comparison operators such as
eq,neq,lt,lte,gt,gte,startsWith,endsWith,contains, andin.
IMPORTANT
The DataCosmos STAC API uses the STAC Query Extension for advanced property filtering. This is distinct from the OGC CQL2 Filter Extension (/filter), which is a newer standard used by some other STAC implementations. The Query Extension uses a query field in the POST body of search requests with operator-based constraints (e.g. {"eo:cloud_cover": {"lte": 20}}).
A Note on Pricing
When retrieving Items from the catalog (whether through the search endpoint, listing items in a collection, or fetching a single item) each Item can include pricing information in its properties (opencosmos:price and opencosmos:price_currency).
Getting prices in search results
Prices are not returned by default. To include opencosmos:price and opencosmos:price_currency in the results you must provide one of the following:
You only need to provide one of the following — they are alternatives, not both required:
| Parameter | Where (POST) | Where (GET) | Description |
|---|---|---|---|
project | JSON body | Query parameter | A project ID. The service resolves the contract automatically via the project's organisation. This is the most common approach. |
contract_id | JSON body | Query parameter | The contract ID to use for pricing directly. Use this if you already know your contract ID and are not working in a project context. |
If neither is provided, opencosmos:price and opencosmos:price_currency are omitted from all returned Items.
Example — POST search using a project ID (recommended):
curl --request POST "https://app.open-cosmos.com/api/data/v0/stac/search" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"collections": ["sentinel-2-l2a"],
"bbox": [-71.72, -27.68, -71.02, -27.06],
"limit": 5,
"project": "your-project-id"
}'
Example — POST search using a contract ID directly:
curl --request POST "https://app.open-cosmos.com/api/data/v0/stac/search" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"collections": ["sentinel-2-l2a"],
"bbox": [-71.72, -27.68, -71.02, -27.06],
"limit": 5,
"contract_id": 456
}'
Example — read the price from a single item:
import requests
# Get bearer token and add to session
collection = "mantis-l1d-cogs"
item_id = "MANTIS_L1D_000000_20211001000000_20211001101010_E274"
response = session.get(f"https://app.open-cosmos.com/api/data/v0/stac/collections/{collection}/items/{item_id}")
item = response.json()
price = item.get("properties", {}).get("opencosmos:price")
currency = item.get("properties", {}).get("opencosmos:price_currency")
print(f"Price: {price} {currency}")
Example — read prices from search results:
import requests
# Get bearer token and add to session
body = {
"bbox": [-71.71875, -27.68, -71.01, -27.05],
"collections": ["mantis-l1d-cogs"],
}
response = session.post("https://app.open-cosmos.com/api/data/v0/stac/search", json=body)
results = response.json()
for feature in results.get("features", []):
item_id = feature["id"]
price = feature.get("properties", {}).get("opencosmos:price")
currency = feature.get("properties", {}).get("opencosmos:price_currency")
print(f"Item: {item_id} - Price: {price} {currency}")
Important considerations
- Prices are calculated dynamically on every request. They are not stored as part of the Item metadata. Each time you request an Item, the price is freshly computed based on your account's contract terms.
- Prices are personalised. The price returned is specific to the authenticated user making the request. Different users may see different prices for the same Item depending on their contract.
- Do not store or cache prices. Because prices depend on your contract terms and may change over time, you should always retrieve a fresh price from the API before presenting it to end users or using it in purchasing decisions. Any previously retrieved price should be treated as indicative only.
- The currency is included alongside the price. Always use the
opencosmos:price_currencyfield to determine the currency of the quoted price rather than assuming a default.
API Examples
Search Collections
Requesting all available Collections is useful when initially exploring the API to see what data is available to you.
Bash
curl --request GET "https://app.open-cosmos.com/api/data/v0/stac/collections" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session
response = session.get("https://app.open-cosmos.com/api/data/v0/stac/collections")
print(response.json())
Search Items in a Collection
Once you have found a Collection that you are interested in, you can search through all the Items it contains.
The search endpoint accepts a collections query parameter to filter by collection. Search parameters are passed as URL query parameters.
This example returns a list of items from the specified Collection within a bounding box. If the results exceed the limit, they will be paginated. The full list of query parameters is documented in the Search API.
Bash
curl --request GET "https://app.open-cosmos.com/api/data/v0/stac/search?collections=mantis-l1d-cogs&bbox=160.6,-55.95,-170,-25.89&limit=100/2021-03-18T12:31:12Z" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session
params = {
"collections": "mantis-l1d-cogs",
"bbox": [160.6, -55.95, -170, -25.89],
"limit": 100,
}
response = session.get("https://app.open-cosmos.com/api/data/v0/stac/search", params=params)
print(response.json())
Advanced Search
The search endpoint also supports a POST request, allowing search parameters to be specified in the request body rather than the URL.
The body supports all the same parameters as the GET request. In addition, the query field supports advanced property filtering using the STAC Query Extension, which defines comparison operators (eq, neq, lt, lte, gt, gte, startsWith, endsWith, contains, in).
NOTE
The DataCosmos API uses the STAC Query Extension for property-based filtering — not the OGC CQL2 Filter Extension. While CQL2 is the newer OGC standard adopted by some STAC APIs, our implementation supports the Query Extension syntax shown below.
This example searches for all Items within a given bounding box with less than 20% cloud coverage.
Bash
curl --request POST "https://app.open-cosmos.com/api/data/v0/stac/search" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"bbox": [
-71.71875,-27.683528083787767,-71.015625,-27.05912578437406
],
"query":{
"eo:cloudcover":{
"lte": 20
}
}
}'
Python
import requests
# Get bearer token and add to session
body = {
"bbox": [-71.71875,-27.683528083787767,-71.015625,-27.05912578437406],
"query": {
"eo:cloudcover": {
"lte": 20,
},
},
}
response = session.post("https://app.open-cosmos.com/api/data/v0/stac/search", json=body)
print(response.json())
Working with Project Items
If you have access to a specific project, you can retrieve and search for items within that project using dedicated endpoints. These endpoints behave similarly to the regular STAC collection endpoints but are specific to project data.
Get all Items from a Project
Bash
curl --request GET "https://app.open-cosmos.com/api/data/v0/scenario/scenario/YOUR-PROJECT-ID/items" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session
project_id = "YOUR-PROJECT-ID"
response = session.get(f"https://app.open-cosmos.com/api/data/v0/scenario/scenario/{project_id}/items")
print(response.json())
Search for Items in a Project
To find specific items within a project, such as the newest items, use the project search endpoint. This endpoint only accepts POST and allows filtering by various parameters including dates.
Bash
curl --request POST "https://app.open-cosmos.com/api/data/v0/scenario/scenario/YOUR-PROJECT-ID/search" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"datetime": "2023-01-01T00:00:00Z/2023-12-31T23:59:59Z"
}'
Python
import requests
# Get bearer token and add to session
project_id = "YOUR-PROJECT-ID"
body = {
"datetime": "2023-01-01T00:00:00Z/2023-12-31T23:59:59Z"
}
response = session.post(f"https://app.open-cosmos.com/api/data/v0/scenario/scenario/{project_id}/search", json=body)
print(response.json())
Get an Item
A single Item can be retrieved when its ID is known. This is useful for storing a reference to an Item and querying it again later.
Bash
curl --request GET "https://app.open-cosmos.com/api/data/v0/stac/collections/mantis-l1d-cogs/items/MANTIS_L1D_000000_20211001000000_20211001101010_E274" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session
collection = "mantis-l1d-cogs"
item = "MANTIS_L1D_000000_20211001000000_20211001101010_E274"
response = session.get(f"https://app.open-cosmos.com/api/data/v0/stac/collections/{collection}/items/{item}")
print(response.json())
Checking Item Access Permissions
Each Item contains a property indicating whether you have full access to its high-resolution assets:
opencosmos:high_resolution_read_permission:truemeans the authenticated user has full access to all assets;falseindicates limited access.
import requests
# Get bearer token and add to session
collection = "mantis-l1d-cogs"
item_id = "MANTIS_L1D_000000_20211001000000_20211001101010_E274"
response = session.get(f"https://app.open-cosmos.com/api/data/v0/stac/collections/{collection}/items/{item_id}")
item = response.json()
has_full_access = item.get("properties", {}).get("opencosmos:high_resolution_read_permission", False)
print(f"Has full access to high-resolution assets: {has_full_access}")
Download Assets from an Item
The assets field of an Item contains links to all source data. The most relevant field is href, which provides a direct download URL.
This example retrieves a specific item and downloads all its assets to local storage.
Bash
curl --request GET "https://app.open-cosmos.com/api/data/v0/stac/collections/mantis-l1d-cogs/items/MANTIS_L1D_000000_20211001000000_20211001101010_E274" \
--header "Content-Type: application/json" --header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session
collection = "mantis-l1d-cogs"
item = "MANTIS_L1D_000000_20211001000000_20211001101010_E274"
response = session.get(f"https://app.open-cosmos.com/api/data/v0/stac/collections/{collection}/items/{item}")
item = response.json()
for _, asset in item["assets"].items():
asset_content = session.get(asset["href"])
with open(asset["title"], "wb") as fp:
fp.write(asset_content.content)
Where to Next