Skip to content

Sentinel-2 L2A

Available now Collection id sentinel-2-l2a. Aliases include sentinel-2-c1-l2a (Earth Search), S2L2A (Sentinel Hub) and SENTINEL2_L2A (CDSE openEO), matched without regard to case.

Sentinel-2 is the Copernicus programme’s optical mission. Each satellite carries the MultiSpectral Instrument (MSI), which records 13 bands from visible light to shortwave infrared at 10, 20 and 60 m. Level-2A is bottom-of-atmosphere reflectance, produced by ESA’s Sen2Cor processor, which also writes a scene classification layer and cloud and snow probabilities.

satellitedata.net serves Collection 1, ESA’s consistent reprocessing of the archive, as Element 84 indexes it in Earth Search under sentinel-2-c1-l2a. The files are cloud-optimized GeoTIFFs in public S3 buckets in AWS us-west-2, the same region the API runs in. Item ids stay native, for example S2A_T31TCF_20260829T105044_L2A.

Mission references: ESA SentiWiki on the Sentinel-2 mission, its processing levels and products; the AWS registry entry for Sentinel-2 COGs.

Satellites Sentinel-2A (launched 2015), 2B (2017) and 2C (2024); item platform is sentinel-2a, sentinel-2b or sentinel-2c
Spatial resolution 10 m (B02, B03, B04, B08), 20 m (red edge, B8A, SWIR, SCL), 60 m (B01, B09)
Revisit 5 days at the equator with two satellites in orbit, more often at higher latitudes
Swath 290 km
Tiling MGRS grid; each item covers one 110 × 110 km tile, such as 31TCF (item property grid:code = MGRS-31TCF)
Processing level Level-2A, bottom-of-atmosphere reflectance (Sen2Cor), Collection 1
Temporal extent in the API From 27 June 2015, as the live collection document reports; see data availability for gaps
Zoom range for tiles 8 to 15
Credit line Contains modified Copernicus Sentinel data {years}

Spectral bands, with the wavelengths and bandwidths Earth Search publishes in each item’s eo:bands. ESA publishes slightly different spectral response figures per satellite; see SentiWiki for those.

Band Common name Earth Search asset Also accepted Centre (nm) Bandwidth (nm) Resolution Type Scale Offset Nodata
B01 coastal coastal CoastalAerosol 443 27 60 m uint16 0.0001 −0.1 0
B02 blue blue B2 490 98 10 m uint16 0.0001 −0.1 0
B03 green green B3 560 45 10 m uint16 0.0001 −0.1 0
B04 red red B4 665 38 10 m uint16 0.0001 −0.1 0
B05 rededge071 rededge1 RedEdge1 704 19 20 m uint16 0.0001 −0.1 0
B06 rededge075 rededge2 RedEdge2 740 18 20 m uint16 0.0001 −0.1 0
B07 rededge078 rededge3 RedEdge3 783 28 20 m uint16 0.0001 −0.1 0
B08 nir nir NIR_Broad, B8 842 145 10 m uint16 0.0001 −0.1 0
B8A nir08 nir08 NIR_Narrow 865 33 20 m uint16 0.0001 −0.1 0
B09 nir09 nir09 WaterVapor 945 26 60 m uint16 0.0001 −0.1 0
B11 swir16 swir16 SWIR1 1610 143 20 m uint16 0.0001 −0.1 0
B12 swir22 swir22 SWIR2 2190 242 20 m uint16 0.0001 −0.1 0

Earth Search’s own common name for B05, B06 and B07 is rededge; the API uses the STAC 1.1 names rededge071, rededge075 and rededge078 so that each one is unique.

Class, probability and atmosphere layers:

Layer Earth Search asset Also accepted Content Resolution Type Scale Offset Nodata
SCL scl Scene classification, classes 0 to 11 20 m uint8 none 0 0
CLD cloud MSK_CLDPRB Cloud probability, 0 to 100 % 20 m uint8 none 0 0
SNW snow MSK_SNWPRB Snow probability, 0 to 100 % 20 m uint8 none 0 0
AOT aot Aerosol optical thickness at 550 nm 20 m uint16 0.001 0 0
WVP wvp Water vapour column in cm 20 m uint16 0.001 0 0

Every name in the tables resolves in POST /v1/process: the native name, the common name, the asset name and the aliases, without regard to case. The GeoTIFF’s band descriptions are the Earth Search asset names.

B10, the 1,375 nm cirrus band, is not part of Level-2A. ESA uses it during atmospheric correction and keeps it only in Level-1C, which is coming later.

Stored values are integers. Collection 1 reflectance is:

reflectance = DN × 0.0001 − 0.1

The −0.1 offset is ESA’s BOA_ADD_OFFSET of −1,000, introduced with processing baseline 04.00 in January 2022. Collection 1 reprocessed the older scenes to the same convention, so every item in this collection carries the offset, and its raster:bands metadata says so. Do not choose the offset from the acquisition date.

What you get depends on three processing options in POST /v1/process:

units harmonize Spectral bands come back as Sample type
REFLECTANCE (default) either DN × 0.0001 − 0.1 FLOAT32, nodata NaN
DN offset_removed (default) DN − 1,000, so DN = 10,000 × reflectance INT16
DN none stored DN, with the scale and offset written into the GeoTIFF UINT16, nodata 0
  • clipNegative: true sets converted values below zero to zero, which is what Sentinel Hub’s harmonizeValues does. On the older download API the same switch is clamp: true.
  • output.sampleType is optional. If you give it, it must match the table. INT16 on its own selects DN with offset_removed.
  • With REFLECTANCE, AOT and WVP get their scale too (unitless and cm). SCL, CLD and SNW always come back as stored.

See Values, scale and offset and Harmonization levels.

Each item has eo:cloud_cover, the percentage of the scene Sen2Cor flags as cloud. Filter scenes with it in search (query), tiles (maxCloudCoverage) and process (dataFilter.maxCloudCoverage).

For pixels, request SCL as a band:

SCL Class
0 No data
1 Saturated or defective pixel
2 Dark area or topographic shadow
3 Cloud shadow
4 Vegetation
5 Not vegetated
6 Water
7 Unclassified
8 Cloud, medium probability
9 Cloud, high probability
10 Thin cirrus
11 Snow or ice

A common clear-pixel rule keeps classes 4, 5 and 6. Class 7 is a judgement call; Sentinel Hub and Earth Engine treat it as cloud. Sen2Cor draws no buffer around clouds, so growing the cloud and shadow areas by a few pixels helps at the edges.

CLD and SNW give Sen2Cor’s cloud and snow probability per pixel, 0 to 100, if you want your own threshold instead of SCL’s classes.

Lean v1 applies no pixel cloud mask: tiles and previews show every pixel of the scenes they mosaic, and processing.cloudMask is rejected. The unified cloud mask, built from SCL with optional dilation, is planned.

Earth Search rebuilt its Sentinel-2 index as sentinel-2-c1-l2a from ESA’s Collection 1. On 16 October 2026 we compared it with Earth Search’s original sentinel-2-l2a over two test areas, in Borneo (about 117.9 to 118.2 E, 1.5 to 1.7 N) and Sulawesi (about 120.0 to 120.2 E, 3.2 to 3.4 S). Collection 1 was complete for 2020 to 2021 and 2023 to 2026. It was missing these scenes:

Year Borneo: missing of original Sulawesi: missing of original
2017 31 of 31 20 of 21
2018 75 of 115 39 of 59
2019 30 of 144 15 of 73
2022 132 of 144 67 of 73

These are gaps observed in the source collection over two small areas, not a global figure. The gaps may be smaller elsewhere, and they may close as reprocessing continues. Before relying on a period, run /v1/search for your area and dates and count what comes back.

Values before 2022. Scenes acquired before baseline 04.00 are ESA’s reprocessed product, with newer atmospheric correction and geometry than the products first published for those dates. Their values can differ from originally processed products, such as Sentinel Hub’s, by up to about 0.02 reflectance. From baseline 04.00 (2022) on, the two match.

Lean v1 search takes the STAC query extension, which Earth Search evaluates. CQL2 filter answers invalid-filter. These properties work in query:

Property Example Notes
eo:cloud_cover {"eo:cloud_cover": {"lte": 20}} Scene cloud percentage
platform {"platform": {"in": ["sentinel-2b", "sentinel-2c"]}} One satellite or several
grid:code {"grid:code": {"eq": "MGRS-31TCF"}} One MGRS tile. Earth Search’s Collection 1 items have no s2:mgrs_tile; they carry grid:code and mgrs:utm_zone, mgrs:latitude_band, mgrs:grid_square

Each item also carries s2:processing_baseline, such as 05.12.

From GET /v1/presets, the web map’s recipes for this collection:

Preset Assets Stretch
true-color visual (the 8-bit TCI image) as stored
false-color nir (B08), red, green DN 1,000 to 5,000, reflectance 0 to 0.4
ndvi nir (B08), red (b1 - b2) / (b1 + b2 - 2000), −0.2 to 0.8 on rdylgn

The NDVI expression subtracts the two 1,000 offsets in the denominator; the offsets cancel in the numerator. Default cloud ceiling 30 % (60 % for ndvi), least cloudy scene first, a 30-day window.

Tiles exist from zoom 8 to 15. Outside that range a tile answers 400 zoom-out-of-range.

Routes marked anonymous need no key. The others send your key in X-API-Key; see Authentication. The examples use the area west of Tarragona, Spain, and August 2026.

Anonymous.

Terminal window
curl -s https://api.satellitedata.net/v1/collections/sentinel-2-l2a

The document lists the bands from schema v1, sdn:aliases, sdn:attribution and sdn:zoom. /v1/collections/S2L2A returns the same document with a Content-Location header.

Terminal window
curl -s -X POST https://api.satellitedata.net/v1/search \
-H "X-API-Key: $SDN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"collections": ["sentinel-2-l2a"],
"bbox": [0.7, 40.7, 0.8, 40.8],
"datetime": "2026-08-01T00:00:00Z/2026-08-31T23:59:59Z",
"limit": 10,
"query": {"eo:cloud_cover": {"lte": 20}}
}'

The next link of a POST search has method: POST and a body holding only token; merge it into your body to get the next page. pystac-client does that for you; see Search.

Anonymous.

Terminal window
curl -s https://api.satellitedata.net/v1/collections/sentinel-2-l2a/items/S2A_T31TCF_20260829T105044_L2A

Asset href values point at the public COGs, which you can read directly without a key.

Terminal window
curl -s -o preview.png \
-H "X-API-Key: $SDN_API_KEY" \
"https://api.satellitedata.net/v1/collections/sentinel-2-l2a/items/S2A_T31TCF_20260829T105044_L2A/preview.png?preset=true-color&max_size=256"

preset is true-color, false-color or ndvi; max_size is the long edge in pixels, 64 to 1,024. The preset’s formats in /v1/presets lists the image formats it serves (ndvi has no JPEG).

The TileJSON is anonymous; the tiles need the key.

Terminal window
curl -s "https://api.satellitedata.net/v1/tiles/true-color/WebMercatorQuad/tilejson.json?collection=sentinel-2-l2a&datetime=2026-08-01/2026-08-31&maxCloudCoverage=20"
{
"tilejson": "3.0.0",
"name": "true-color",
"attribution": "Contains modified Copernicus Sentinel data 2026",
"tiles": ["https://api.satellitedata.net/v1/tiles/true-color/WebMercatorQuad/{z}/{x}/{y}.png?collection=sentinel-2-l2a&datetime=2026-08-01%2F2026-08-31&maxCloudCoverage=20"],
"minzoom": 8,
"maxzoom": 15
}

(Shortened.) One tile from that template, at zoom 12 over Tarragona’s hinterland:

Terminal window
curl -s -o tile.png -H "X-API-Key: $SDN_API_KEY" \
"https://api.satellitedata.net/v1/tiles/true-color/WebMercatorQuad/12/2055/1534.png?collection=sentinel-2-l2a&datetime=2026-08-01%2F2026-08-31&maxCloudCoverage=20"

In MapLibre, give the TileJSON URL as a raster source and add the key with transformRequest, as in the Quickstart and Map tiles.

A 2 km box from the scenes of 29 August 2026, in UTM zone 31N. REFLECTANCE is the default; it is written out here for clarity.

Terminal window
curl -s -L -X POST https://api.satellitedata.net/v1/process \
-H "X-API-Key: $SDN_API_KEY" \
-H "Content-Type: application/json" \
-o truecolor.tif \
-d '{
"input": {
"bounds": {"bbox": [0.73815, 40.71096, 0.76185, 40.72904]},
"data": [{
"type": "sentinel-2-l2a",
"dataFilter": {"timeRange": {"from": "2026-08-29T00:00:00Z", "to": "2026-08-29T23:59:59Z"}},
"processing": {"units": "REFLECTANCE"}
}]
},
"bands": ["red", "green", "blue"],
"output": {"width": 200, "height": 150, "crs": "EPSG:32631"}
}'

red and nir08 as INT16, where DN = 10,000 × reflectance on every baseline. sampleType: "INT16" selects units: "DN" with harmonize: "offset_removed".

Terminal window
curl -s -L -X POST https://api.satellitedata.net/v1/process \
-H "X-API-Key: $SDN_API_KEY" \
-H "Content-Type: application/json" \
-o ndvi-inputs.tif \
-d '{
"input": {
"bounds": {"bbox": [0.73815, 40.71096, 0.76185, 40.72904]},
"data": [{
"type": "S2L2A",
"dataFilter": {"timeRange": {"from": "2026-08-29T00:00:00Z", "to": "2026-08-29T23:59:59Z"}}
}]
},
"bands": ["red", "nir08"],
"output": {"width": 200, "height": 150, "crs": "EPSG:32631", "sampleType": "INT16"}
}'

Then NDVI is (nir08 - red) / (nir08 + red) on the integers directly, because the offset is already gone. Add "processing": {"units": "DN", "clipNegative": true} to the data source for Sentinel Hub’s harmonized values.

Synchronous process stops at 2,500 pixels a side. For more, send the same body to /v1/process/jobs and poll. This one is a 20 km box at 5 m.

Terminal window
curl -s -i -X POST https://api.satellitedata.net/v1/process/jobs \
-H "X-API-Key: $SDN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"bounds": {"bbox": [0.63147, 40.62956, 0.86853, 40.81044]},
"data": [{
"type": "sentinel-2-l2a",
"dataFilter": {"ids": ["S2A_T31TCF_20260829T105044_L2A"]}
}]
},
"bands": ["blue", "green", "red", "nir08"],
"output": {"width": 4000, "height": 4000, "crs": "EPSG:32631"}
}'
# 202 Accepted, with Location: https://api.satellitedata.net/v1/process/jobs/{jobId}
curl -s -H "X-API-Key: $SDN_API_KEY" https://api.satellitedata.net/v1/process/jobs/$JOB_ID

A job goes queued, running, then done or failed. See Process jobs for the limits.