Search for available data

Before downloading satellite data it is important to know exactly which data is available and what kind of properties it has. Sentinel Hub offers multiple services to search collections of data:

In this example tutorial we will show how to use each of the services.

Some general imports:

[1]:
%matplotlib inline

import datetime as dt

import matplotlib.pyplot as plt
import numpy as np

from sentinelhub import CRS, BBox, DataCollection, SHConfig

Sentinel Hub Catalog API

Catalog API is the main service with the most configurable search options. It supports searches over all available data collections and provides the most information about each item in a collection. The implementation is based on STAC REST API specifications.

More information about the service is available in:

Prerequisites

Copernicus Data Space Ecosystem users must configure according to Copernicus Data Space Ecosystem Configuration.

[2]:
config = SHConfig()

if config.sh_client_id == "" or config.sh_client_secret == "":
    print("Warning! To use Sentinel Hub Catalog API, please provide the credentials (client ID and client secret).")

Available data collections

In the first, step let’s initialize a SentinelHubCatalog class and check basic service info:

[3]:
from sentinelhub import SentinelHubCatalog

catalog = SentinelHubCatalog(config=config)

catalog.get_info()
[3]:
{'type': 'Catalog',
 'stac_version': '1.0.0',
 'id': 'sentinel-hub',
 'title': 'Sentinel Hub STAC catalog',
 'description': 'STAC v1.0.0 implementation by Sentinel Hub',
 'conformsTo': ['http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core',
  'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/oas30',
  'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/geojson',
  'https://api.stacspec.org/v1.0.0/core',
  'https://api.stacspec.org/v1.0.0/collections',
  'https://api.stacspec.org/v1.0.0/ogcapi-features',
  'https://api.stacspec.org/v1.0.0/ogcapi-features#fields',
  'https://api.stacspec.org/v1.0.0/ogcapi-features#context',
  'https://api.stacspec.org/v1.0.0/ogcapi-features#filter',
  'https://api.stacspec.org/v1.0.0/item-search',
  'https://api.stacspec.org/v1.0.0/item-search#fields',
  'https://api.stacspec.org/v1.0.0/item-search#context',
  'https://api.stacspec.org/v1.0.0/item-search#filter',
  'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter',
  'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter',
  'http://www.opengis.net/spec/cql2/1.0/conf/cql2-text',
  'http://www.opengis.net/spec/cql2/1.0/conf/cql2-json',
  'http://www.opengis.net/spec/cql2/1.0/conf/basic-cql2'],
 'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
   'rel': 'root',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
   'rel': 'self',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
   'rel': 'data',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/conformance',
   'rel': 'conformance',
   'type': 'application/json',
   'title': 'STAC conformance classes implemented by this server'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/search',
   'rel': 'search',
   'type': 'application/geo+json',
   'title': 'STAC search',
   'method': 'GET'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/search',
   'rel': 'search',
   'type': 'application/geo+json',
   'title': 'STAC search',
   'method': 'POST'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/queryables',
   'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
   'type': 'application/schema+json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l1c',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 2 L1C'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-olci',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 3 OLCI'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-slstr',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 3 SLSTR'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 1 GRD'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 2 L2A'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-5p-l2',
   'rel': 'child',
   'type': 'application/json',
   'title': 'Sentinel 5 Precursor'},
  {'href': 'https://documentation.dataspace.copernicus.eu/APIs/SentinelHub/ApiReference/openapi.v1.yaml',
   'rel': 'service-desc',
   'type': 'application/vnd.oai.openapi;version="3.1"',
   'title': 'OpenAPI service description'},
  {'href': 'https://documentation.dataspace.copernicus.eu/APIs/SentinelHub/ApiReference.html#tag/catalog_core',
   'rel': 'service-doc',
   'type': 'text/html',
   'title': 'OpenAPI service documentation'}]}

Each data collection has its own catalog collection. The default collections are already listed in the info response. Information about all available collections, including user-defined BYOC and batch collections, can be obtained with the next example.

The following code will obtain information about all collections but then filter out BYOC and batch collections:

[4]:
collections = catalog.get_collections()

collections = [collection for collection in collections if not collection["id"].startswith(("byoc", "batch"))]

collections
[4]:
[{'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/eo/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-2-l1c',
  'title': 'Sentinel 2 L1C',
  'description': 'Sentinel 2 imagery processed to level 1C',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [{'name': 'ESA',
    'roles': ['producer'],
    'url': 'https://esa.int/'},
   {'name': 'CDSE',
    'roles': ['processor', 'host'],
    'url': 'https://dataspace.copernicus.eu/'},
   {'name': 'Sinergise',
    'roles': ['processor'],
    'url': 'https://www.sinergise.com/'}],
  'extent': {'spatial': {'bbox': [[-180.0, -56.0, 180.0, 83.0]]},
   'temporal': {'interval': [['2015-11-01T00:00:00Z', None]]}},
  'summaries': {'platform': ['sentinel-2a', 'sentinel-2b'],
   'instrument': ['msi'],
   'constellation': ['sentinel-2'],
   'gsd': [10],
   'eo:cloud_cover': {'minimum': 0, 'maximum': 100},
   'eo:bands': [{'name': 'B01',
     'common_name': 'coastal',
     'center_wavelength': 0.4427,
     'full_width_half_max': 0.021},
    {'name': 'B02',
     'common_name': 'blue',
     'center_wavelength': 0.4924,
     'full_width_half_max': 0.066},
    {'name': 'B03',
     'common_name': 'green',
     'center_wavelength': 0.5598,
     'full_width_half_max': 0.036},
    {'name': 'B04',
     'common_name': 'red',
     'center_wavelength': 0.6646,
     'full_width_half_max': 0.031},
    {'name': 'B05', 'center_wavelength': 0.7041, 'full_width_half_max': 0.015},
    {'name': 'B06', 'center_wavelength': 0.7405, 'full_width_half_max': 0.015},
    {'name': 'B07', 'center_wavelength': 0.7828, 'full_width_half_max': 0.02},
    {'name': 'B08',
     'common_name': 'nir',
     'center_wavelength': 0.8328,
     'full_width_half_max': 0.106},
    {'name': 'B8A',
     'common_name': 'nir08',
     'center_wavelength': 0.8647,
     'full_width_half_max': 0.021},
    {'name': 'B09',
     'common_name': 'nir09',
     'center_wavelength': 0.9451,
     'full_width_half_max': 0.02},
    {'name': 'B10',
     'common_name': 'cirrus',
     'center_wavelength': 1.3735,
     'full_width_half_max': 0.031},
    {'name': 'B11',
     'common_name': 'swir16',
     'center_wavelength': 1.6137,
     'full_width_half_max': 0.091},
    {'name': 'B12',
     'common_name': 'swir22',
     'center_wavelength': 2.2024,
     'full_width_half_max': 0.175}]},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l1c',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l1c/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l1c/items',
    'rel': 'items',
    'type': 'application/geo+json'}]},
 {'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/sat/v1.0.0/schema.json',
   'https://stac-extensions.github.io/eo/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-3-olci',
  'title': 'Sentinel 3 OLCI',
  'description': 'Sentinel 3 imagery captured by OLCI sensor',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [],
  'extent': {'spatial': {'bbox': [[-180.0, -85.0, 180.0, 85.0]]},
   'temporal': {'interval': [['2016-04-17T11:33:13Z', None]]}},
  'summaries': {'platform': ['sentinel-3'],
   'instrument': ['olci'],
   'gsd': [300],
   'sat:orbit_state': ['ascending', 'descending'],
   'eo:bands': [{'name': 'B01',
     'center_wavelength': 0.4,
     'full_width_half_max': 0.015},
    {'name': 'B02', 'center_wavelength': 0.4125, 'full_width_half_max': 0.01},
    {'name': 'B03', 'center_wavelength': 0.4425, 'full_width_half_max': 0.01},
    {'name': 'B04', 'center_wavelength': 0.49, 'full_width_half_max': 0.01},
    {'name': 'B05', 'center_wavelength': 0.51, 'full_width_half_max': 0.01},
    {'name': 'B06', 'center_wavelength': 0.56, 'full_width_half_max': 0.01},
    {'name': 'B07', 'center_wavelength': 0.62, 'full_width_half_max': 0.01},
    {'name': 'B08', 'center_wavelength': 0.665, 'full_width_half_max': 0.01},
    {'name': 'B09',
     'center_wavelength': 0.67375,
     'full_width_half_max': 0.0075},
    {'name': 'B10',
     'center_wavelength': 0.68125,
     'full_width_half_max': 0.0075},
    {'name': 'B11', 'center_wavelength': 0.70875, 'full_width_half_max': 0.01},
    {'name': 'B12',
     'center_wavelength': 0.75375,
     'full_width_half_max': 0.0075},
    {'name': 'B13',
     'center_wavelength': 0.76125,
     'full_width_half_max': 0.0025},
    {'name': 'B14',
     'center_wavelength': 0.764375,
     'full_width_half_max': 0.00375},
    {'name': 'B15',
     'center_wavelength': 0.7675,
     'full_width_half_max': 0.0025},
    {'name': 'B16',
     'center_wavelength': 0.77875,
     'full_width_half_max': 0.015},
    {'name': 'B17', 'center_wavelength': 0.865, 'full_width_half_max': 0.02},
    {'name': 'B18', 'center_wavelength': 0.885, 'full_width_half_max': 0.01},
    {'name': 'B19', 'center_wavelength': 0.9, 'full_width_half_max': 0.01},
    {'name': 'B20', 'center_wavelength': 0.94, 'full_width_half_max': 0.02},
    {'name': 'B21', 'center_wavelength': 1.02, 'full_width_half_max': 0.04}]},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-olci',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-olci/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-olci/items',
    'rel': 'items',
    'type': 'application/geo+json'}]},
 {'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/sat/v1.0.0/schema.json',
   'https://stac-extensions.github.io/eo/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-3-slstr',
  'title': 'Sentinel 3 SLSTR',
  'description': 'Sentinel 3 imagery captured by SLSTR sensor',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [],
  'extent': {'spatial': {'bbox': [[-180.0, -85.0, 180.0, 85.0]]},
   'temporal': {'interval': [['2016-04-17T11:33:13Z', None]]}},
  'summaries': {'platform': ['sentinel-3'],
   'instrument': ['slstr'],
   'gsd': [1000],
   'sat:orbit_state': ['ascending', 'descending'],
   'eo:bands': [{'name': 'S01',
     'center_wavelength': 0.55427,
     'full_width_half_max': 0.01926},
    {'name': 'S02',
     'center_wavelength': 0.65947,
     'full_width_half_max': 0.01925},
    {'name': 'S03', 'center_wavelength': 0.868, 'full_width_half_max': 0.0206},
    {'name': 'S04',
     'center_wavelength': 1.3748,
     'full_width_half_max': 0.0208},
    {'name': 'S05',
     'center_wavelength': 1.6134,
     'full_width_half_max': 0.06068},
    {'name': 'S06',
     'center_wavelength': 2.2557,
     'full_width_half_max': 0.05015},
    {'name': 'S07', 'center_wavelength': 3.742, 'full_width_half_max': 0.398},
    {'name': 'S08', 'center_wavelength': 10.854, 'full_width_half_max': 0.776},
    {'name': 'S09',
     'center_wavelength': 12.0225,
     'full_width_half_max': 0.905},
    {'name': 'F01', 'center_wavelength': 3.742, 'full_width_half_max': 0.398},
    {'name': 'F02',
     'center_wavelength': 10.854,
     'full_width_half_max': 0.776}]},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-slstr',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-slstr/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-3-slstr/items',
    'rel': 'items',
    'type': 'application/geo+json'}]},
 {'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/sat/v1.0.0/schema.json',
   'https://stac-extensions.github.io/sar/v1.0.0/schema.json',
   'https://docs.sentinel-hub.com/api/latest/stac/s1/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-1-grd',
  'title': 'Sentinel 1 GRD',
  'description': 'Sentinel 1 Ground Range Detected Imagery',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [],
  'extent': {'spatial': {'bbox': [[-180.0, -85.0, 180.0, 85.0]]},
   'temporal': {'interval': [['2014-10-03T00:00:00Z', None]]}},
  'summaries': {'platform': ['sentinel-1a', 'sentinel-1b'],
   'instrument': ['c-sar'],
   'constellation': ['sentinel-1'],
   'sat:orbit_state': ['ascending', 'descending'],
   'sar:instrument_mode': ['SM', 'IW', 'EW', 'WV'],
   'sar:frequency_band': ['C'],
   'sar:center_frequency': [5.405],
   'sar:product_type': ['GRD'],
   'sar:polarizations': ['HH', 'HV', 'VH', 'VV'],
   'sar:resolution_range': [9.0, 20.0, 23.0, 50.0, 52.0, 84.0, 88.0, 93.0],
   'sar:resolution_azimuth': [9.0, 22.0, 23.0, 50.0, 51.0, 84.0, 87.0],
   'sar:pixel_spacing_range': [3.5, 10.0, 25.0, 40.0],
   'sar:pixel_spacing_azimuth': [3.5, 10.0, 25.0, 40.0],
   's1:timeliness': ['NRT10m',
    'NRT1h',
    'NRT3h',
    'Fast24h',
    'Offline',
    'Reprocessing',
    'ArchNormal'],
   's1:resolution': ['HIGH', 'MEDIUM', 'FULL'],
   's1:polarization': ['SH', 'SV', 'DH', 'DV', 'HH', 'HV', 'VV', 'VH']},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd/items',
    'rel': 'items',
    'type': 'application/geo+json'}]},
 {'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/eo/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-2-l2a',
  'title': 'Sentinel 2 L2A',
  'description': 'Sentinel 2 imagery processed to level 2A',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [{'name': 'ESA',
    'roles': ['producer'],
    'url': 'https://esa.int/'},
   {'name': 'CDSE',
    'roles': ['processor', 'host'],
    'url': 'https://dataspace.copernicus.eu/'},
   {'name': 'Sinergise',
    'roles': ['processor'],
    'url': 'https://www.sinergise.com/'}],
  'extent': {'spatial': {'bbox': [[-180.0, -56.0, 180.0, 83.0]]},
   'temporal': {'interval': [['2016-11-01T00:00:00Z', None]]}},
  'summaries': {'platform': ['sentinel-2a', 'sentinel-2b'],
   'instrument': ['msi'],
   'constellation': ['sentinel-2'],
   'gsd': [10],
   'eo:cloud_cover': {'minimum': 0, 'maximum': 100},
   'eo:bands': [{'name': 'B01',
     'common_name': 'coastal',
     'center_wavelength': 0.4427,
     'full_width_half_max': 0.021},
    {'name': 'B02',
     'common_name': 'blue',
     'center_wavelength': 0.4924,
     'full_width_half_max': 0.066},
    {'name': 'B03',
     'common_name': 'green',
     'center_wavelength': 0.5598,
     'full_width_half_max': 0.036},
    {'name': 'B04',
     'common_name': 'red',
     'center_wavelength': 0.6646,
     'full_width_half_max': 0.031},
    {'name': 'B05', 'center_wavelength': 0.7041, 'full_width_half_max': 0.015},
    {'name': 'B06', 'center_wavelength': 0.7405, 'full_width_half_max': 0.015},
    {'name': 'B07', 'center_wavelength': 0.7828, 'full_width_half_max': 0.02},
    {'name': 'B08',
     'common_name': 'nir',
     'center_wavelength': 0.8328,
     'full_width_half_max': 0.106},
    {'name': 'B8A',
     'common_name': 'nir08',
     'center_wavelength': 0.8647,
     'full_width_half_max': 0.021},
    {'name': 'B09',
     'common_name': 'nir09',
     'center_wavelength': 0.9451,
     'full_width_half_max': 0.02},
    {'name': 'B11',
     'common_name': 'swir16',
     'center_wavelength': 1.6137,
     'full_width_half_max': 0.091},
    {'name': 'B12',
     'common_name': 'swir22',
     'center_wavelength': 2.2024,
     'full_width_half_max': 0.175}]},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a/items',
    'rel': 'items',
    'type': 'application/geo+json'}]},
 {'stac_version': '1.0.0',
  'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
   'https://stac-extensions.github.io/sat/v1.0.0/schema.json',
   'https://docs.sentinel-hub.com/api/latest/stac/s5p/v1.0.0/schema.json'],
  'type': 'Collection',
  'id': 'sentinel-5p-l2',
  'title': 'Sentinel 5 Precursor',
  'description': 'Sentinel 5 Precursor imagery captured by TROPOMI sensor',
  'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
  'license': 'proprietary',
  'providers': [],
  'extent': {'spatial': {'bbox': [[-180.0, -85.0, 180.0, 85.0]]},
   'temporal': {'interval': [['2018-04-30T00:18:50Z', None]]}},
  'summaries': {'platform': ['sentinel-5 precursor'],
   'instrument': ['tropomi'],
   'gsd': [7000],
   'sat:orbit_state': ['ascending', 'descending'],
   's5p:type': ['O3',
    'O3_TCL',
    'O3_PR',
    'O3_TPR',
    'NO2',
    'SO2',
    'CO',
    'CH4',
    'HCHO',
    'CLOUD',
    'AER_AI',
    'AER_LH',
    'FRESCO',
    'BD3',
    'BD6',
    'BD7'],
   's5p:timeliness': ['NRTI', 'OFFL', 'RPRO']},
  'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
    'rel': 'root',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-5p-l2',
    'rel': 'self',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
    'rel': 'parent',
    'type': 'application/json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-5p-l2/queryables',
    'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
    'type': 'application/schema+json'},
   {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-5p-l2/items',
    'rel': 'items',
    'type': 'application/geo+json'}]}]

Information about a single collection can also be obtained with the following method:

[5]:
catalog.get_collection(DataCollection.SENTINEL1_EW)
[5]:
{'stac_version': '1.0.0',
 'stac_extensions': ['https://stac-extensions.github.io/scientific/v1.0.0/schema.json',
  'https://stac-extensions.github.io/sat/v1.0.0/schema.json',
  'https://stac-extensions.github.io/sar/v1.0.0/schema.json',
  'https://docs.sentinel-hub.com/api/latest/stac/s1/v1.0.0/schema.json'],
 'type': 'Collection',
 'id': 'sentinel-1-grd',
 'title': 'Sentinel 1 GRD',
 'description': 'Sentinel 1 Ground Range Detected Imagery',
 'sci:citation': 'Modified Copernicus Sentinel data [Year]/Sentinel Hub',
 'license': 'proprietary',
 'providers': [],
 'extent': {'spatial': {'bbox': [[-180.0, -85.0, 180.0, 85.0]]},
  'temporal': {'interval': [['2014-10-03T00:00:00Z', None]]}},
 'summaries': {'platform': ['sentinel-1a', 'sentinel-1b'],
  'instrument': ['c-sar'],
  'constellation': ['sentinel-1'],
  'sat:orbit_state': ['ascending', 'descending'],
  'sar:instrument_mode': ['SM', 'IW', 'EW', 'WV'],
  'sar:frequency_band': ['C'],
  'sar:center_frequency': [5.405],
  'sar:product_type': ['GRD'],
  'sar:polarizations': ['HH', 'HV', 'VH', 'VV'],
  'sar:resolution_range': [9.0, 20.0, 23.0, 50.0, 52.0, 84.0, 88.0, 93.0],
  'sar:resolution_azimuth': [9.0, 22.0, 23.0, 50.0, 51.0, 84.0, 87.0],
  'sar:pixel_spacing_range': [3.5, 10.0, 25.0, 40.0],
  'sar:pixel_spacing_azimuth': [3.5, 10.0, 25.0, 40.0],
  's1:timeliness': ['NRT10m',
   'NRT1h',
   'NRT3h',
   'Fast24h',
   'Offline',
   'Reprocessing',
   'ArchNormal'],
  's1:resolution': ['HIGH', 'MEDIUM', 'FULL'],
  's1:polarization': ['SH', 'SV', 'DH', 'DV', 'HH', 'HV', 'VV', 'VH']},
 'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
   'rel': 'root',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd',
   'rel': 'self',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections',
   'rel': 'parent',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd/queryables',
   'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
   'type': 'application/schema+json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-1-grd/items',
   'rel': 'items',
   'type': 'application/geo+json'}]}

Search features in catalog collections

Once we have successfully initialized a catalog object we can search for features inside a specific collection. If we have an ID of a satellite tile we can search for its information like this:

[6]:
catalog.get_feature(
    DataCollection.SENTINEL2_L2A,
    "S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE",
)
[6]:
{'stac_version': '1.0.0',
 'stac_extensions': ['https://stac-extensions.github.io/eo/v1.0.0/schema.json',
  'https://stac-extensions.github.io/projection/v1.0.0/schema.json'],
 'id': 'S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE',
 'type': 'Feature',
 'geometry': {'type': 'MultiPolygon',
  'crs': {'type': 'name',
   'properties': {'name': 'urn:ogc:def:crs:OGC::CRS84'}},
  'coordinates': [[[[50.99975828238186, 45.15382824779532],
     [52.39639823709577, 45.14529082814174],
     [52.37288170686682, 44.15712570690993],
     [50.99976235468337, 44.16537549736596],
     [50.99975828238186, 45.15382824779532]]]]},
 'bbox': [50.99975828238186,
  44.15712570690993,
  52.39639823709577,
  45.15382824779532],
 'properties': {'datetime': '2021-01-25T07:37:20.296Z',
  'platform': 'sentinel-2a',
  'instruments': ['msi'],
  'constellation': 'sentinel-2',
  'gsd': 10,
  'eo:cloud_cover': 1.18,
  'proj:epsg': 32639,
  'proj:bbox': [499980.0, 4890240.0, 609780.0, 5000040.0],
  'proj:geometry': {'type': 'MultiPolygon',
   'crs': {'type': 'name',
    'properties': {'name': 'urn:ogc:def:crs:EPSG::32639'}},
   'coordinates': [[[[499980.99999999994, 5000039.000149707],
      [609779.0000017696, 5000039.000149423],
      [609779.000001563, 4890241.000125842],
      [499980.99999999965, 4890241.0001261],
      [499980.99999999994, 5000039.000149707]]]]}},
 'assets': {'data': {'href': 's3://EODATA/Sentinel-2/MSI/L2A_N0500/2021/01/25/S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE',
   'title': 's3',
   'type': 'inode/directory'}},
 'collection': 'sentinel-2-l2a',
 'links': [{'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/',
   'rel': 'root',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a/items/S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE',
   'rel': 'self',
   'type': 'application/geo+json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a',
   'rel': 'parent',
   'type': 'application/json'},
  {'href': 'https://sh.dataspace.copernicus.eu/api/v1/catalog/1.0.0/collections/sentinel-2-l2a',
   'rel': 'collection',
   'type': 'application/json'}]}

For any more advanced search we can use SentinelHubCatalog.search method. The method always requires a data collection, time interval and a bounding box or a geometry. Additionally, we can define various STAC-based query filters which are described in documentation and API definition.

In our case, we will filter all satellite tiles with more than 5% cloud coverage. To reduce the size of downloaded responses we will also filter fields that will be returned in the response.

[7]:
caspian_sea_bbox = BBox((49.9604, 44.7176, 51.0481, 45.2324), crs=CRS.WGS84)
time_interval = "2020-12-10", "2021-02-01"

search_iterator = catalog.search(
    DataCollection.SENTINEL2_L2A,
    bbox=caspian_sea_bbox,
    time=time_interval,
    filter="eo:cloud_cover < 5",
    fields={"include": ["id", "properties.datetime", "properties.eo:cloud_cover"], "exclude": []},
)

results = list(search_iterator)
print("Total number of results:", len(results))

results
Total number of results: 12
[7]:
[{'id': 'S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE',
  'properties': {'datetime': '2021-01-25T07:37:20.296Z',
   'eo:cloud_cover': 1.18}},
 {'id': 'S2A_MSIL2A_20210125T073201_N0500_R049_T39TVL_20230528T024029.SAFE',
  'properties': {'datetime': '2021-01-25T07:37:09.425Z',
   'eo:cloud_cover': 4.0}},
 {'id': 'S2A_MSIL2A_20210125T073201_N0500_R049_T39TWL_20230528T024029.SAFE',
  'properties': {'datetime': '2021-01-25T07:37:05.835Z',
   'eo:cloud_cover': 0.43}},
 {'id': 'S2A_MSIL2A_20210105T073311_N0500_R049_T39TWK_20230404T141905.SAFE',
  'properties': {'datetime': '2021-01-05T07:37:20.216Z',
   'eo:cloud_cover': 2.56}},
 {'id': 'S2A_MSIL2A_20201226T073321_N0500_R049_T39TWK_20230414T073429.SAFE',
  'properties': {'datetime': '2020-12-26T07:37:19.181Z',
   'eo:cloud_cover': 2.61}},
 {'id': 'S2A_MSIL2A_20201226T073321_N0500_R049_T39TVL_20230414T073429.SAFE',
  'properties': {'datetime': '2020-12-26T07:37:08.298Z',
   'eo:cloud_cover': 3.06}},
 {'id': 'S2A_MSIL2A_20201226T073321_N0500_R049_T39TWL_20230414T073429.SAFE',
  'properties': {'datetime': '2020-12-26T07:37:04.725Z',
   'eo:cloud_cover': 1.9}},
 {'id': 'S2A_MSIL2A_20201216T073321_N0500_R049_T39TWL_20230323T215920.SAFE',
  'properties': {'datetime': '2020-12-16T07:37:02.951Z',
   'eo:cloud_cover': 2.88}},
 {'id': 'S2B_MSIL2A_20201211T073219_N0500_R049_T39TVK_20230225T222516.SAFE',
  'properties': {'datetime': '2020-12-11T07:37:20.568Z',
   'eo:cloud_cover': 0.26}},
 {'id': 'S2B_MSIL2A_20201211T073219_N0500_R049_T39TWK_20230225T222516.SAFE',
  'properties': {'datetime': '2020-12-11T07:37:16.885Z',
   'eo:cloud_cover': 1.65}},
 {'id': 'S2B_MSIL2A_20201211T073219_N0500_R049_T39TVL_20230225T222516.SAFE',
  'properties': {'datetime': '2020-12-11T07:37:06.001Z',
   'eo:cloud_cover': 0.0}},
 {'id': 'S2B_MSIL2A_20201211T073219_N0500_R049_T39TWL_20230225T222516.SAFE',
  'properties': {'datetime': '2020-12-11T07:37:02.436Z',
   'eo:cloud_cover': 1.01}}]

Combine Catalog API with Process API

With Catalog API we were able to get information all satellites tiles for a given bounding box and time interval. Let’s see how we can use this information with Process API to download data for all acquisitions.

We can see that many timestamps differ only for a few seconds. That is because they are from tiles in the same orbit acquisition. Because of that, we want to join them together in a single timestamp.

[8]:
from sentinelhub import MimeType, SentinelHubDownloadClient, SentinelHubRequest, bbox_to_dimensions, filter_times

time_difference = dt.timedelta(hours=1)

all_timestamps = search_iterator.get_timestamps()
unique_acquisitions = filter_times(all_timestamps, time_difference)

unique_acquisitions
[8]:
[datetime.datetime(2020, 12, 11, 7, 37, 2, 436000, tzinfo=tzutc()),
 datetime.datetime(2020, 12, 16, 7, 37, 2, 951000, tzinfo=tzutc()),
 datetime.datetime(2020, 12, 26, 7, 37, 4, 725000, tzinfo=tzutc()),
 datetime.datetime(2021, 1, 5, 7, 37, 20, 216000, tzinfo=tzutc()),
 datetime.datetime(2021, 1, 25, 7, 37, 5, 835000, tzinfo=tzutc())]

Next, we create a Process API request for each acquisition:

[9]:
false_color_evalscript = """
    //VERSION=3

    function setup() {
        return {
            input: [{
                bands: ["B03", "B04", "B08"]
            }],
            output: {
                bands: 3
            }
        };
    }

    function evaluatePixel(sample) {
        return [sample.B08, sample.B04, sample.B03];
    }
"""


process_requests = []

for timestamp in unique_acquisitions:
    request = SentinelHubRequest(
        evalscript=false_color_evalscript,
        input_data=[
            SentinelHubRequest.input_data(
                data_collection=DataCollection.SENTINEL2_L2A.define_from("s2l2a", service_url=config.sh_base_url),
                time_interval=(timestamp - time_difference, timestamp + time_difference),
            )
        ],
        responses=[SentinelHubRequest.output_response("default", MimeType.PNG)],
        bbox=caspian_sea_bbox,
        size=bbox_to_dimensions(caspian_sea_bbox, 100),
        config=config,
    )
    process_requests.append(request)

In order to efficiently download data for all requests in parallel, we extract download information and pass it to a download client.

[10]:
%%time

client = SentinelHubDownloadClient(config=config)

download_requests = [request.download_list[0] for request in process_requests]

data = client.download(download_requests)

data[0].shape
CPU times: user 245 ms, sys: 51.1 ms, total: 296 ms
Wall time: 1.58 s
[10]:
(567, 861, 3)

Downloaded images nicely show how the ice cover has been changing over Caspian Sea during winter.

[11]:
ncols, nrows = 2, 3

fig, axis = plt.subplots(
    ncols=ncols, nrows=nrows, figsize=(15, 10), subplot_kw={"xticks": [], "yticks": [], "frame_on": False}
)

for idx, (image, timestamp) in enumerate(zip(data, unique_acquisitions)):
    ax = axis[idx // ncols][idx % ncols]
    ax.imshow(np.clip(image * 2.5 / 255, 0, 1))
    ax.set_title(timestamp.date().isoformat(), fontsize=10)

plt.tight_layout()
../_images/examples_data_search_cdse_22_0.png

Web Feature Service (WFS)

This is an OGC-based service that allows searching with a bounding box and time interval. Instead of OAuth credentials, it requires an instance ID of a configuration created in Sentinel Hub Dashboard. For each data collection that you search you have to make sure that you have at least one layer with that data collection defined in a configuration that you are using.

More information can be found in WFS service documentation.

[12]:
from sentinelhub import WebFeatureService

# In case you put the credentials into the configuration file you can leave this unchanged
INSTANCE_ID = ""

config = SHConfig()
if INSTANCE_ID:
    config.instance_id = INSTANCE_ID

Let’s search with the same parameters used in the Catalog API example above. We obtain the same number of results but with a bit different types of information in properties.

[13]:
caspian_sea_bbox = BBox((49.9604, 44.7176, 51.0481, 45.2324), crs=CRS.WGS84)
time_interval = "2020-12-10", "2021-02-01"

wfs_iterator = WebFeatureService(
    caspian_sea_bbox,
    time_interval,
    data_collection=DataCollection.SENTINEL2_L2A.define_from("s2l2a", service_url=config.sh_base_url),
    maxcc=0.05,
    config=config,
)


results = list(wfs_iterator)
print("Total number of results:", len(results))

results[0]
Total number of results: 12
[13]:
{'type': 'Feature',
 'geometry': {'type': 'MultiPolygon',
  'crs': {'type': 'name',
   'properties': {'name': 'urn:ogc:def:crs:EPSG::4326'}},
  'coordinates': [[[[50.999758282381855, 45.15382824914294],
     [52.396398237151104, 45.14529082948613],
     [52.37288170691262, 44.157125708042365],
     [50.99976235468336, 44.16537549850127],
     [50.999758282381855, 45.15382824914294]]]]},
 'properties': {'date': '2021-01-25',
  'time': '07:37:20.296',
  'path': 'creo://EODATA/Sentinel-2/MSI/L2A_N0500/2021/01/25/S2A_MSIL2A_20210125T073201_N0500_R049_T39TWK_20230528T024029.SAFE/GRANULE/L2A_T39TWK_A029218_20210125T073204/IMG_DATA/RRESOLUTION/T39TWK_20210125T073201_TILEBAND_RESOLUTION',
  'crs': 'EPSG:32639',
  'mbr': '499980,4890240 609780,5000040',
  'cloudCoverPercentage': 1.18}}