In the Copernicus Data Space Ecosystem (CDSE), OData (Open Data Protocol) is the primary RESTful API standard used for searching, discovering, and downloading satellite data products.
Key functions of OData in CDSE are:
This package provides convenient wrappers to access those features, and are described in this vignette.
The package also offers features for the complementary alternative
catalogue via STAC. For more details on that read
vignette("STAC").
For searching products, you could simply use
dse_odata_products(), where you could directly add filters
as arguments. But for more sophisticated queries, you can use
dse_odata_products_request(). It creates a special class of
httr2 request object. In essence, it is a request to the
API server, which you can modify with tidyverse operators. This sounds
more complicated than it is.
Once you have created the request, you can add tidyverse operators
(like filter(), arrange() and
slice_head()), to modify this request. You can join those
modifications with the pipe operator (|> or
%>%). You can also query products that intersect with
specific spatial features (sf) using
st_intersects().
Each collection will have specific fields which you can use to filter
your product search. To discover which fields you use, call
dse_odata_attributes().
All of this is shown in the example below, where we filter products
that were created after January first of 2025. Where the image overlaps
with the bounding box we specify. We create a descending arrangement of
identifiers, and select only the first 5 results. By calling
collect() we ensure that the request is performed and the
result is returned in a human readable form
(data.frame).
library(CopernicusDataspace)
library(dplyr) # Tidiverse package for data manipulation
library(sf) # package for handling simple (spatial) features
## Define a bounding box for our search query:
bbox <-
st_bbox(
c(xmin = 5.261, ymin = 52.680, xmax = 5.319, ymax = 52.715),
crs = 4326) |>
st_as_sfc()
## Create an API request:
dse_odata_products_request() |>
## Filter content on ContentDate/Start`:
filter(
`ContentDate/Start` > "2025-01-01") |>
## Only data that intersects with our bounding box:
st_intersects(bbox) |>
## Arrange by descending Id:
arrange(desc(Id)) |>
## Only the first 5 hits:
slice_head(n = 5) |>
## Collect the results:
collect()
#> # A tibble: 5 × 16
#> Id Name ContentType ContentLength OriginDate PublicationDate
#> <chr> <chr> <chr> <int> <chr> <chr>
#> 1 ffff1bb2-405d-49c2… MCD4… applicatio… 54771356 2025-04-3… 2025-11-09T22:…
#> 2 fffec6a0-62da-45ef… c_gl… applicatio… 2281083 2025-07-1… 2025-07-11T12:…
#> 3 fffdd7f0-cd27-4c3e… S5P_… applicatio… 11349305 2026-05-0… 2026-05-09T13:…
#> 4 fffd6992-b724-4a5d… c_gl… applicatio… 1080239294 2026-02-2… 2026-02-23T02:…
#> 5 fffd6520-0f19-49fc… c_gl… applicatio… 11559794 2025-10-3… 2025-10-31T16:…
#> # ℹ 10 more variables: ModificationDate <chr>, Online <lgl>,
#> # EvictionDate <chr>, S3Path <chr>, Checksum <list>, ContentDate.Start <chr>,
#> # ContentDate.End <chr>, Footprint <chr>, GeoFootprint.type <chr>,
#> # GeoFootprint.coordinates <list>Bursts
is a concept associated with the Sentinel-1 C-SAR instrument. They have
dedicated functions for searching for specific burst data:
dse_odata_bursts() and
dse_odata_bursts_request(). These are the equivalents of
dse_odata_products() and
dse_odata_products_request(). They work with the same
mechanisms and downloading them works the same as for normal OData
products, as shown below. Below a basic example of looking for and
downloading of burst data:
Once you have identified an interesting product, there are ways to
further explore it. You need the product identifier (ID) to do so. With
dse_odata_product_nodes() you can see which files are
associated with the product:
dse_odata_product_nodes("c8ed8edb-9bef-4717-abfd-1400a57171a4",
recursive = TRUE)
#> # A tibble: 6 × 5
#> Id Name ContentLength ChildrenNumber Nodes.uri
#> <chr> <chr> <int> <int> <chr>
#> 1 S6A_P4_2__LR______20250110T11091… S6A_… 0 5 https://…
#> 2 xfdumanifest.xml xfdu… 126456 0 https://…
#> 3 EOPMetadata.xml EOPM… 13800 0 https://…
#> 4 S6A_P4_2__LR_RED__NT_153_196_202… S6A_… 1410175 0 https://…
#> 5 S6A_P4_2__LR_STD__NT_153_196_202… S6A_… 10670647 0 https://…
#> 6 manifest.xml mani… 1727 0 https://…If available you can also get a quick peek at your product by calling
dse_odata_quicklook():
As shown in the ‘exploring’ section above, products can contain
‘nodes’, which could either represent a file or a directory. If you want
to download all files in such a directory you can call
dse_odata_download_path(). It will download all files in
the specified node path. This is demonstrated below:
if (dse_has_account()) {
dse_odata_download_path(
product = "2f497806-0101-5eea-83fa-c8f68bc56b0c",
node_path =
paste("DEM1_SAR_DTE_90_20101213T034716_20130408T035028_ADS_000000_5033.DEM",
"Copernicus_DSM_30_S09_00_E026_00", "DEM",
"Copernicus_DSM_30_S09_00_E026_00_DEM.dt1", sep = "/"),
destination = tempdir()
)
}The example above uses an alternative https route and requires a
private access token, which in turn requires your Copernicus Data Space
user id (usually your e-mail address) and password (see
vignette("Authentication")).
The formal OData route uses [S3 buckets](https://en.wikipedia.org/wiki/Amazon_S3 and requires S3
authentication (see vignette("Authentication")). You can
perform such downloads with dse_odata_downloads() as shown
below