Sentinel Hub forum is the best place to get in touch with support staff as well as other Sentinel Hub users.

You can find Quick tutorial on Sentinel Hub here.

You can find the Sentinel Hub forum here. Select your category of interest and you might find your question already answered. If not, ask and our team or other users will help you find a solution.

If you don't have the EO Browser/Sentinel Hub account yet:

To receive our bimonthly newsletter and stay updated with important news, we invite you to create a new free account here. After choosing desired subscription preferences and enabling the option to receive latest news and information on Sentinel Hub, confirm it by clicking the Sign up button. You will receive the verification email, follow the link in it and stay updated.

If you already have the EO Browser/Sentinel Hub account:

Log in to the Sentinel Hub Dashboard with your credentials (email and password). Choose the User settings tab and enable the option for receiving the latest news under Marketing premissions. Confirm your choice by clicking the Save Changes button.

The newsletters are released every 2 months and are archived on our newsletters page, where you can explore all the news you might have missed.

You can cite our applications / web pages in the following way (link is optional):

When referring to Sentinel data acquired through the Sentinel Hub services, please use the following credit:

  • "Modified Copernicus Sentinel data [Year]/Sentinel Hub"

To delete your profile and remove your personal information from our web page, go to the Sentinel Hub Dashborad. Under the "User settings" tab click on "Delete profile" button and confirm your decision by clicking one more time on "Yes, delete profile" button in the pop-up window.

Subscription, Packages and Pricing

Our subscription plans are described here:

The difference between consumer / research and commercial plan is in the purpose of the usage of our services. If you are using the Sentinel Hub services for research purposes or for yourself, consumer / research option is the right one. If you are using it within your company, you should use commercial option.

MissionProductResolution [m]km2 for one PU€ per 1 km2
Sentinel-2True color1026.20.00006
All 13 bands106.00.00025
Sentinel-1VV gamma0 ortho20157.30.00001
Sentinel-3 OCITrue color30023 593.00.00000007
OTCI30035 389.40.00000004
Landsat-8True color - pansharpened1544.20.00003

VAT will be charged if you are purchasing our services as:

  • not VAT registered company in the EU
  • an individual from the EU or outside the EU

VAT won’t be charged if you are purchasing our services as:

  • VAT registered company in the EU
  • company outside the EU

Yes. You can go to the Dashboard and choose a recurrent subscription option.

This gives you an option to set-up automatically recurrent payment by PayPal, which you can cancel at any time.

Generally we advise to subscribe for an annual package as it comes with a discount.

To pay for the Sentinel Hub services you can choose between the following options:

  • PayPal
  • credit card (all supported by Adyen)
  • wire-transfer

If you decide to subscribe, go to the Dashboard and choose one of the plans.

To change your payment method, two steps are needed:

1. You have to revoke existing subscription, which you can do in the Sentinel Hub Dashboard under the Billing tab / Order History. More details on how to revoke a subscription are described here. Your account will remain active until one month after the last payment.

2. Before your account expires, you have to establish a new subscription with your prefered payment method in the Sentinel Hub Dasboard under the Billing tab / Plans.

You can cancel your subscription to the Sentinel Hub services in the Sentinel Hub Dashboard. The link will take you to the "Billing" option in the menu left and your "History" list. All you need to do is to click on the "Revoke subscription" button and confirm your choice. Your status will be changed to "revoked" and subscription canceled.

There is no pricing plan activated in a trial stage. You are getting full access to the system, without technical limitations.

Please note, that the Sentinel Hub trial account is not allowed for commercial use.

After 30 days you can decide, which subscription service you want and subscribe. There is no automatic payment.

There is no difference in functionality or data between trial account and subscription account, apart of trial account being limited to 30,000 requests per month and 300 processing units per minute. As we would like to give all users the opportunity to test the Sentinel Hub services at its fullest, you can contact us if you need higher throughput in the trial phase.

The trial use is completely free and there will be no costs associated to it whatsoever. You do not need to cancel your account after the trial period expires, and there are no automatic charges.

After 30 days of the trial period:

  • The access to OGC services will expire, but you will still be able to use EO Browser for non-commercial purpose.
  • To continue using OGC services you will have the ability to subscribe to one of the plans directly in the Sentinel Hub Dashboard.

We do not charge anything automatically, nor do we extend a subscription period automatically. A week before the end of subscription period you will be notified about incoming event and asked, whether you would like to extend the subscription. In case your decide for an extension, you will be asked for additional payment. In the opposite case, account will be frozen for one month period and deleted afterwards.

If you decide for extending the subscription, go to the Dashboard and choose one of the plans.
This gives you an option to set-up automatically recurrent payment by PayPal or credit card, which you can cancel at any time.

Yes, there are ESA sponsored accounts available. Go to the Network of resources page and click Submit a request to receive sponsorship for a Platform Service.

Make sure you include the most relevant information:

  • Which services you need (e.g. EDC Sentinel Hub, EDC Batch Processing, etc.)
  • In case access to commercial data is needed (EDC PlanetScope, EDC Airbus Pleiades or EDC Airbus SPOT), state the desired volume
  • The planned volume of data uptake (best to reference processing units or sq. km)
  • Desired duration of the access (up to 12 months)
  • Scientifically relevant results planned to result from the exercise
  • In case of business exploration activities some plans for long-term sustainability.
  • Make sure to press Submit at the end of the process.

    You can find example mobile app here.

    Note that the subscription option does not include the mobile app itself. This is simply an option of the service best suited for integration in various apps.

    A definition of a processing unit is avaliable in our documentation. The rules with examples of how to calculate the number of processing units for a request are also provided.

    Individual subscription is meant for one, named user. She or he can use it at any device but this account cannot be shared amongst different users.

    Available EO Data

    Sentinel-2 - global coverage, full archive
    Sentinel-3 - global coverage, full OLCI archive
    Sentinel-1 - global coverage, full GRD archive
    Sentinel-5P - global coverage
    Landsat-8 USGS - global coverage, almost full archive
    Landsat-5, 7 and 8 - ESA Archive - Europe and North Africa, full archive
    ENVISAT MERIS - global coverage, full archive
    Digital Elevation Model – DEM - a static dataset based on MapZen's DEM updates
    MODIS - Terra and Aqua

    For more details check also our list of available data sources on our web page.

    To explore availability, please check EO Browser, and Sentinel Playground (for DEM).

    To browse various data, go to EO Browser. Read about how to use it here.

    We have our services installed on several places to get fastest access to the data. This is why there are different access points for different data sources. To learn which configurator you should use to configure your own configurations and layers, or which endpoints to use with OGC or Process API, visit our page on datasources or our documentation for more details.

    We put a lot of effort to make data available as soon as possible. However, we depend almost entirely on how fast the data provider can process and disseminate the data.

    For Sentinel products, ESA usually makes them available on their OpenHub in 6-12 hours (target timing is 3-6 hours, sometimes it takes longer, even more than one day). We instantly pull data down but as it takes some time to download complete data, it might take up to one additional hour before they are available on Sentinel Hub.

    The best way to get information about all the available scenes in a specific area is to use our Catalog service API, which will give you detailed geospatial information for each tile, that you can control by specifying fields, limits and other properties. For this specific use case, it is most useful to use the `distinct` parameter with `date`, which will return a list of the available dates for your requested BBOX and time range. To make this Catalog API request, import the following CURL request to Postman. You will need to authenticate the request with a token.

    curl -X POST '' \
    -header 'Authorization: Bearer <your access token>' \
    -header 'Content-Type: application/json' \
    -data-raw '{
        "bbox": [13,45,14,46],
        "datetime": "2019-12-10T00:00:00Z/2020-12-15T00:00:00Z",
        "collections": ["sentinel-1-grd"],
        "limit": 50,
        "distinct": "date"

    In the curl request above, the first line is the URL for the request, that you only need to change if you’re using datasets on different deployments. The first header is where you add your access token; if you authenticate the collection or the request in Postman, the token will be automatically added. The second header is where you specify the desired output, which in this case, is a JSON file. In data-raw, you will specify the bbox, time range (datetime), dataset collection (collections), limit (the upper limit of the number of results), and with the line "distinct":"date", you will limit your results to only include information on the acquisition date. Consult the Catalog API reference to learn more about the available parameters.

    The result for the CURL request above will look like this:

        "type": "FeatureCollection",
        "features": [
        "links": [
                "href": "",
                "rel": "self",
                "type": "application/json"
        "context": {
            "limit": 50,
            "returned": 4

    At the beginning of the result, you can see all the available dates listed for your request.

    It’s also possible to search the available scenes using OGC WFS request, which might be a bit easier to use, but gives you much less search control.

    To make a WFS request, you will need to add your INSTANCE_ID, specify the bbox, timerange (TIME), dataset collection (TYPENAMES), coordinate system (srsName) and a request type. Read more on the parameters here. An example WFS request would look like this:,5039853,3244050,5045897&TIME=2019-02-11/2019-02-12

    You can test the WFS examples with different parameters and inspect the results instantly here.

    Note that you can also use MAXCC parameter (maximum cloud coverage) in this call to filter for cloudless data.

    Use FEATURE_OFFSET parameter to control the starting point within the returned features and MAXFEATURES parameter the maximum number of parameter of features to be returned by a single request.

    As a result you will get a list of all the available scenes for the chosen location in JSON format (or XML if set so). Some of the dates may be duplicated if there are two scenes available in the area. You should simply ignore these duplications.

    Note: this description is deprecated as we are moving to V3 processing as described in this post.
    At this moment the explanation below is still valid when using V1 and V2 EVALSCRIPs and when using SIMPLE EVALSCRIPTs with OGC API.
    For V3 EVALSCRIPTs and for SIMPLE EVALSCRIPTs the behaviour is described in the documentation.

    This is a bit complicated as it depends on several design decisions we’ve had to make in order to keep our service as generic as possible.

    There are several basic rules used within Sentinel Hub:

    • whenever we work with sensor data (e.g. B02, B08, etc.), a reflectance value is used
    • when outputting the value from the system, it is clamped to the range 0-1 and then stretched to the range of values of the format of the output:
      • if format is 32-bit float, it is 0-1
      • if format is 16-bit, it is 0-65535; 0 -> 0 and 1 -> 65535
      • if format is 8-bit, it is 0-255; 0 -> 0 and 1 -> 255
    • IEEE 754 single-precision is used within calculations (e.g. 32-bit float)
    • internally during script evaluation, there is no clamping being done

    As an example, if one wants to get Sentinel-2 reflectance values, one can use this simple custom script:
    return [B02];

    And depending on the output format will return:

    • reflectance values where reflectance = 1 is at a pixel value of 65535 (format=image/tiff;depth=16)
    • reflectance values where reflectance = 1 is at a pixel value of 255 (format=image/tiff;depth=8, format=image/jpg  or format=image/png)
    • reflectance values in the range 0-1 (format=image/tiff;depth=32f)

    If one is calculating NDVI, e.g.:
    var ndvi = (B08-B04)/(B08+B04);
    return [ndvi];

    This will return:

    • range 0-1 adjusted to an integer 0-65535 for 16 bit output (format=image/tiff;depth=16)
    • range 0-1 adjusted to an integer 0-255 if 8 bit output (format=image/tiff;depth=8, format=image/jpg  or format=image/png)
    • range 0-1 if 32 bit float output (format=image/tiff;depth=32f)

    As NDVI values can sometimes be negative (e.g. -0.2) or if using a different index with values more than 1 (e.g. 1.5), one has to adapt the output if one wants to get this information. E.g. if one expects an index value from -1 to 2, the final script would have to be adapted to:
    index = (index+1)/3;
    The output between 0 and 1 can be there mapped like that:

    • output 0 -> value -1
    • output 0.333 -> value 0
    • output 0.667 -> value 1
    • output 1 -> value =2

    Note that if one’s desired output is color visualisation, this can be as simple as this:

    return colorBlend(ndvi, 
      [-0.2, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 ],[
      [0, 0, 0], // < -.2 = #000000 (black) 
      [165/255,0,38/255], // -> 0 = #a50026 
      [215/255,48/255,39/255], // -> .1 = #d73027 
      [244/255,109/255,67/255], // -> .2 = #f46d43 
      [253/255,174/255,97/255], // -> .3 = #fdae61 
      [254/255,224/255,139/255], // -> .4 = #fee08b 
      [255/255,255/255,191/255], // -> .5 = #ffffbf 
      [217/255,239/255,139/255], // -> .6 = #d9ef8b 
      [166/255,217/255,106/255], // -> .7 = #a6d96a 
      [102/255,189/255,99/255], // -> .8 = #66bd63 
      [26/255,152/255,80/255], // -> .9 = #1a9850 
      [0,104/255,55/255] // -> 1.0 = #006837 

    Yes, the atmospherically corrected Sentinel-2 L2A data is available globally since 2017. For Europe it is available since 2015. For more information about S2L2A visit our atmospheric correction page and our documentation.

    Some areas never have cloud coverage below 20%. This is why in Playground, where we have default setting for 20% of cloud coverage, for some areas seems there is no satellite imagery available. However if we turn slider for maximum cloud coverage to 100%, we can see data available.

    We would like to serve data as they are, without uncontrolled changes, because it is almost impossible to set color balance to one fitting all places in the world and all groups of users. You can still tweak contrast in several ways.

    Figure 1: Raw picture.

    You can tweak "Gain" (brightness) to automatically equalize the image.

    Figure 2: Gain adjusted to desired values.

    You can tweak "Gamma" (contrast) as well.

    Figure 3: Gamma adjusted to desired values.

    Use the atmospheric correction by using the S2L2A atmospherically corrected data instead of S2L1C. As you can see on the image below, atmospheric correction increases the contrast, as it corrects for the effects of the atmosphere.

    Figure 4: Atmospheric correction with S-2 L2A.

    Source Data Using the WFS Request

    To access metadata of the scene or to see which tiles are available, use the WFS request. Get started by checking out the WFS use examples.

    Source Data Using the WFS Request on S3

    In case one needs, for a specific purpose, source data used for some scene, he can use a WFS request with the same parameters as for WMS. A response will contain a path attribute, e.g. something along the lines of:

    "path": "s3://sentinel-s2-l1c/tiles/310/S/DG/2015/12/7/0"

    It is then possible to access these data from AWS, where they are stored by adding relevant filenames, see typical structure of a typical scene at AWS bellow.

    In case you want to download it from outside of AWS network, you can change the address to:

    Typical structure of the scene:

     aws s3 ls s3://sentinel-s2-l1c/tiles/10/S/DG/2015/12/7/0/
                               PRE auxiliary/
                               PRE preview/
                               PRE qi/
    2017-08-27 20:39:26    2844474 B01.jp2
    2017-08-27 20:39:26   83913648 B02.jp2
    2017-08-27 20:39:26   89505314 B03.jp2
    2017-08-27 20:39:26   97645600 B04.jp2
    2017-08-27 20:39:26   27033174 B05.jp2
    2017-08-27 20:39:26   27202251 B06.jp2
    2017-08-27 20:39:26   27621995 B07.jp2
    2017-08-27 20:39:26  100009241 B08.jp2
    2017-08-27 20:39:26    2987729 B09.jp2
    2017-08-27 20:39:26    1218596 B10.jp2
    2017-08-27 20:39:26   27661057 B11.jp2
    2017-08-27 20:39:26   27712884 B12.jp2
    2017-08-27 20:39:26   27909008 B8A.jp2
    2017-08-27 20:39:26  134890604 TCI.jp2
    2017-08-27 20:39:26     379381 metadata.xml
    2017-08-27 20:39:26     166593 preview.jp2
    2017-08-27 20:39:49     106056 preview.jpg
    2017-08-27 20:39:47       1035 productInfo.json
    2017-08-27 20:39:26       1678 tileInfo.json

    We put quite a lot of effort into leaving the data as they are, not to modify it. However, this also means that some data mistakes get to our users. One of these is geolocation shift.

    There is a nice blog post written by CNES colleague Olivier Hagolle on this topic. We suggest to read it and send a notice to ESA and Copernicus to do something about it.

    Due to different licensing model we cannot provide free access to these datasets. One therefore first has to order the image through us (most commonly an on-going monitoring of specific area on daily/weekly/monthly basis). Once this order is processed, we will make the purchased data available through Sentinel Hub services in the same manner as other data.

    EO Browser

    Simply write coordinates in the "Search places" tool in "lat,lon" form, e.g.:


    And click enter

    As EO Browser timelapse functionality has a limit of processing up to 300 images at once, we need to do some post-processing, to be able to create longer timelapses. This can be especially useful with datasets like MODIS, with data available all the way back to the year 2000. Take a look at this MODIS timelapse of the Aral sea, dating from 2002 to 2019.

    First, use command prompt to convert .gif timelapses from EO Browser into .mp4 files and then merge them together. For example, if we want to create an 18 years long timelapse, six timelapses, each three years long, are required. You should first download your smaller timelapses from EO Browser.

    After downloading the gifs from EO Browser, we should transform them into .mp4 files. To do so, we first need to download and install ffmpeg program for making videos. Follow this tutorial to install ffmpeg.

    To test if ffmpeg is installed, go to CMD and type: ffmpeg -version.

    To transform a gif into mp4, first navigate to the folder where your gif files are stored, then open your command prompt and write in the following code:

    ffmpeg -i GIF1.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" GIF1vid.mp4

    The only part of the code you need to change is the name of your gif at the start and the name of the output .mp4 video at the end.

    You need to transform all your .gif timelapses into separate .mp4 files:

    ffmpeg -i GIF1.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" GIF1vid.mp4
    ffmpeg -i GIF2.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" GIF2vid.mp4
    ffmpeg -i GIF3.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" GIF3vid.mp4

    Finally, merge all the .mp4 files into a final .mp4 file with the following code:

    ffmpeg -i GIF1vid.mp4 -i GIF2vid.mp4 -i GIF3vid.mp4 -filter_complex "[0:0] [1:0] [2:0] concat=n=3:v=1:a=0" FinalVideo.mp4

    In this code, we specify the output name of the final .mp4 timelapse and list the .mp4 files we want to merge. We preface the .mp4 files with -i. Then we need to add as many arrays, as there are input .mp4 videos; [0:0] for the first one, [0:1] for the second one, [0:3] for the third one and so on. The n=3 indicates how many input .mp4 files there are.

    For 6 input .mp4 files, the code would look like this:

    ffmpeg -i GIF1vid.mp4 -i GIF2vid.mp4 -i GIF3vid.mp4 -i GIF4vid.mp4 -i GIF5vid.mp4 -i GIF6vid.mp4 - filter_complex "[0:0][1:0][2:0][3:0][4:0][5:0] concat=n=6:v=1:a=0" FinalVideo.mp4

    When you create a custom layer in Sentinel Hub Configuration Utility it is possible to select that layer in EO Browser. To do that, first select your configuration on Search tab, then select the appropriate search result, and in Visualization tab select the said custom layer.

    However such layers usually contains color visualization (RGB) of values. Because Feature Info Service operates on the indicator values themselves (and not on RGB), that means that you must add an additional layer (in Sentinel Hub Configuration Utility) which returns the value without conversion to color. The name of this layer must be constructed from the ID (not name) of the visualization layer:


    That is: double underscore, followed by "FIS", followed by another underscore, followed by original layer's ID. For example, if we would like to use Feature Info on a layer with ID "3-NDVI2", we should add a layer with ID "__FIS_3-NDVI2".

    The data processing script in the newly added "FIS layer" should either:

    • return a single indicator value or
    • return two values, the last of which indicates cloud coverage (1 if the point is covered by the cloud, 0 if not).

    Example data processing script:

    function index(x, y) {
        return (x - y) / (x + y);
    const ndvi = index(B08, B04);
    return [ndvi];

    Example data processing script with cloud coverage:

    function index(x, y) {
        return (x - y) / (x + y);
    const NGDR = index(B03, B04);
    const bRatio = (B03 - 0.175) / (0.39 - 0.175);
    const isCloud = bRatio > 1 || (bRatio > 0 && NGDR > 0);
    const ndvi = index(B08, B04);
    return isCloud ? [ndvi, 1] : [ndvi, 0];

    Note that this answer is specific to EO Browser and the way it uses layers.

    If you are trying to get raw data directly in EO Browser following the SciHub link shown below, please note that SciHub is a 3rd party service operated by Copernicus and you need to have a separate account there.

    You can create it for free here:

    EO Products

    We recommend to check our “EO Products” page as well as Index DataBase, which holds numerous descriptions, along with scientific articles.

    Hover your mouse over the steps below to examine the process.

    Step 1: image Open Configuration utility
    Step 2: image Click "Add new layer" button.
    Step 3: image Enter Layer title.
    Step 4: image Fill the input fields, select "Product" from dropdown menu or write your "Custom script" by clicking on the "Pencil icon".
    Step 5: image Type your custom script and click "Save". See detailed information about custom scripting here.
    Step 6: image Click "Save All" to finish creating new layer.


    For detailed information about WMS configurator click here.

    Choose the NDVI layer in the Sentinel Hub Configuration Utility or set the LAYERS parameter to NDVI (LAYERS=NDVI) in your request URL.

    When user selects "EO Product template", she can see the Custom script behind each visualization/processing to make it as transparent as possible on what is happening with the data. We are changing these configurations through time, adding new ones and improving existing ones. For those, who want to ensure that processing of their layers is not changed any more, they can simply edit the original Custom script and gain full control over it.

    You can get information from scene classification layer produced by Sen2Cor, for data where S2A is available. Data can be retrieved by identifier “SCL” (e.g. instead of return [B02]; for blue color one can use return [SCL/10];).
    Data can be then used for e.g. validation of the pixel value, e.g. along the lines:

              var scl = SCL;
              if (scl == 0) { // No Data
                return [0, 0, 0]; // black
              } else if (scl == 1) { // Saturated / Defective
                return [1, 0, 0.016]; // red
              } else if (scl == 2) { // Dark Area Pixels
                return [0.525, 0.525, 0.525]; // gray
              } else if (scl == 3) { // Cloud Shadows
                return [0.467, 0.298, 0.043]; // brown
              } else if (scl == 4) { // Vegetation
                return [0.063, 0.827, 0.176]; // green
              } else if (scl == 5) { // Bare Soils
                return [1, 1, 0.325]; // yellow
              } else if (scl == 6) { // Water
                return [0, 0, 1]; // blue
              } else if (scl == 7) { // Clouds low probability / Unclassified
                return [0.506, 0.506, 0.506]; // medium gray
              } else if (scl == 8) { // Clouds medium probability
                return [0.753, 0.753, 0.753]; // light gray
              } else if (scl == 9) { // Clouds high probability
                return [0.949, 0.949, 0.949]; // very light gray
              } else if (scl == 10) { // Cirrus
                return [0.733, 0.773, 0.925]; // light blue/purple
              } else if (scl == 11) { // Snow / Ice
                return [0.325, 1, 0.980]; // cyan
              } else { // should never happen
                return [0,0,0];

    Please note that it makes sense to use this layer only on full resolution as any interpolation based on classification codelist will not produce reasonable results. You should also use NEAREST upsampling/downsampling setting, which you can find in "Advanced layer editor" .

    Also please note that this map does not constitute a land cover classification map in a strict sense, its main purpose is to be used internally in Sen2Cor in the atmospheric correction module to distinguish between cloudy pixels, clear pixels and water pixels.

    An example of Blinnenhorn, Switzerland (October 14, 2017):

    Sentinel-2 L2A, SCL, acquired with EO Browser

    Sentinel-2 L2A, true color, acquired with EO Browser

    This is a prototype feature and can change in the future releases.

    Image Manipulation

    If you want to get float values out of the service, you will have to use 32-bit float image type (as basic 8 and 16bit tiff files only support integeres).

    You can define a Custom script along the following lines:

                  var ndvi = (B08-B04)/(B08+B04); 
                    return [ndvi]; 


    You can either save this in Configuration utility or you can pass it as EVALSCRIPT parameter. For the latter the example of the call is:<INSTANCE_ID>?service=WMS&request=GetMap&layers=MY_LAYER&format=image/tiff;depth=32f&maxcc=20&time=

    We suggest to also check the FAQ about details of internal calculation.

    If one wants to have pixels transparent (or semi-transparent), the following can be done:

    • format=image/png (note that PNGs are larger than JPGs, which might affect download speed)
    • custom script output needs to have 4 channels, fourth one being alpha, e.g. "return[1,0,0,0.5]" for semi-transparent red pixel or "return[0,0,0,0]" for full transparency
    • For OGC, parameter TRANSPARENT needs to be set to FALSE not to mix two transparency processes

    E.g. if one wants to have a Hollstein's cloud overview layer shown in a way, that everything except clouds is transparent, she just needs to change

              let naturalColour = [B04, B03, B02].map(a => gain * a);
              let CLEAR  = naturalColour;
              let SHADOW = naturalColour;
              let WATER  = [0.1,0.1,0.7];
              let CIRRUS = [0.8,0.1,0.1];
              let CLOUD  = [0.3,0.3,1.0];
              let SNOW   = [1.0,0.8,0.4];


              let naturalColour = [0,0,0,0];
              let CLEAR  = naturalColour;
              let SHADOW = naturalColour;
              let WATER  = [0.1,0.1,0.7,1];
              let CIRRUS = [0.8,0.1,0.1,1];
              let CLOUD  = [0.3,0.3,1.0,1];
              let SNOW   = [1.0,0.8,0.4,1];

    Note that all other outputs need to be 4-channel ones as well.

    Instead of WIDTH and HEIGHT parameters one can use RESX and RESY.
    E.g. if one adds "RESX=10m&RESY=10m", the image will be returned in 10m resolution.

    To get original reflectance data from the satellite set the custom script accordingly. REFLECTANCE is a physical format, which requires a 32-bit TIFF float. The values ​​are from 0 to 1. See example below:{INSTANCE_ID} ...&LAYERS=B04_REFLECTANCE&FORMAT=image/tiff;depth=32f

    Custom script example for B04_REFLECTANCE:

    return [B04]

    Custom script band input values are already in reflectance (hence the simple script).

    We suggest to also check the FAQ about details of internal calculation.

    There are several options, depending on what you would like to do:

    1. You can use a feature info request and point to some location. The response will contain a date field within it.

    2. You can use the WFS service with the same parameters as used in your WMS request (e.g. date, cloud coverage). You will get a list of features representing scenes fitting the criteria.

    3. You can configure the layer to show acquisition dates.
      • Go to the layer of choice.
      • Click the "Advanced" button in the Layer tab to enter advanced parameters dialogue.
      • (optional) You can turn on Help by clicking on "?" top right.
      • Add "additionalData" node with type "Date"
    4. Click Save in Advanced parameters dialogue and Layers tab.

    Grid of solar zenith angles and grid of solar azimuth angles are accessible by names sunZenithAngles and sunAzimuthAngles, respectively, and can be used in a similar way as band values, e.g.:

      return [sunAzimuthAngles/50]; 
    return [sunZenithAngles/60];

    There are also two grids named viewZenithMean and viewAzimuthMean that contains average viewing incidence angles (zenith and azimuth) across all bands and detectors. They can be used as, e.g.:

      return [viewAzimuthMean/70];
    return [viewZenithMean/80];

    Custom Scripts

    1. Finding the appropriate satellite scene

    • Search for the location of your interest either by scrolling the map with mouse or enter location in the search field on the right side of your screen.
    • Choose from which satellites you want to receive the data (checkboxes on the left side of your screen).
    • Select maximum Cloud coverage percentage.
    • Select time range by either typing the date or select the date from calendar.

    2. In the Results tab choose your candidate satellite image by clicking Visualize button.

    3. In the Visualization tab choose Custom (Create custom rendering) button.

    4. Open the custom script dialog with clicking on the </> icon.

    5. Write your own script or copy custom scripts, which are stored elsewhere, either on Google drive, GitHub or in our Custom script repository. 

    In case the script is too long, check this description.

    For more information on how to create custom scripts check our Custom Script Tutorial and a friendly video guide.

    Custom Script integrates Chrome V8 JavaScript engine, so vast majority of the functions supported there can be used in Custom Script as well. Some of the Evalscript V3 documentation.

    To start creating your own custom scripts, visit our custom scripts page, where you can dive into tutorials, documentation, interesting blogs and start creating your own visualizations.

    Add the EVALSCRIPT parameter to your OGC request URL with the value of the base64 encoded script, as such: evalscript=cmV0dXJuIFtCMDQqMi41LEIwMyoyLjUsQjAyKjIuNV0%3D
    More on custom scripts described here.

    A working WMS request from EO Browser, using a simple custom evaluation script:,B02,B03&evalscript=cmV0dXJuIFtCMDgqMi41LEIwNCoyLjUsQjAzKjIuNV07

    Note that the LAYERS parameter is always going to equal B01,B02,B03 when using a PRESET=CUSTOM with a custom evalscript.

    Custom pixel calculation can be performed by creating a WMS layer with the "custom script" product selected in the Configuration Utility. How to use the script is detailed here.

    Scripts in EO Browser are passed to Sentinel Hub service using "GET request", which is limited in number of characters, depending on the browser used between 1.000 and 4.000.

    But there is an easy way to work around this:
    1. Upload your script to some publicly accessible web-site, for example GitHub, like we do in Custom Script repository. E.g. LAI script.

    2. Select "Use URL" and paste the URL to the script in "Script URL" field

    3. Click Refresh

    In Configuration Utility, it is possible to edit Data Processing of a Layer and observe live changes in Layer's Preview before even saving the Layer. This feature can be useful for tweaking custom scripts parameters.

    Best way to do this is to duplicate a Layer, and open Preview by clicking the "Show preview" button in original and duplicated Layer for easier comparison. Edit one of them to see changes between scripts by opening the Layer's "Data Processing" settings with clicking on the "Pencil" button. After the appropriate EO product is chosen hit the button "Copy script to editor" to tweak the script. After setting the custom script you can immediately inspect the changes in the preview window without saving the Layer.

    You can also choose different EO Products under "Data processing settings".

    With hitting the  button you will reset the layer.

    Please note that this doesn't work for the data sources which are not included in the Sentinel Playground application, such as Sentinel-5P, Sentinel-3, Landsat 5, 7 and others.

    By employing the dynamically interpreted JavaScript language, and providing some specialized functions you can combine the bands of multispectral satellite data in unprecedented ways.

    Here is an example how to tweak the image with a custom script in case of volcano eruption:

    return [
      B04 * 2.5 + Math.max(0, B12 - 0.1),
      B03 * 2.5 + Math.max(0, B11 - 0.1),
      B02 * 2.5

    Erupting vulcano

    Etna volcano eruption, dated 16. 3. 2017. Image combined from true colour image, overlaid with SWIR bands 11 and 12. (view on Sentinel Playground)

    You can find more examples and how to tweak the images for easier detection of Earth surface changes, clouds, snow, shadow, water etc. in our blog post.

    Use the colorBlend method:
    colorBlend(inputValue, indexArray, outputValueArray) The returned value is interpolated between the two consecutive values in outputValueArray (which represent RGB colors normalized to [0,1], e.g. pure red is [1,0,0]) based on the inputValue's location in the indexArray.

    Note the indexArray and outputValueArray must be the same size. For example: return colorBlend(B04,    [0, 0.2, 0.4, 0.6, 0.8, 1],    [[0,0,0], [0.1,0.2,0.5], [0.25,0.4,0.5], [0.4,0.6,0.5], [0.75,0.8,0.5], [1,1,0.5]]); If B04 is 0.25 it will interpolate between [0.1,0.2,0.5] and [0.25,0.4,0.5] since they are the corresponding colors to the 0.2 and 0.4 indices in the indexArray nearest to B04.

    You can use Custom scripts and type in-the code along the following lines:


    function stretch(val, min, max)  {
      return (val-min)/(max-min);
    return [
      stretch(B04, 0.05, 0.5),
      stretch(B03, 0.05, 0.5),
      stretch(B02, 0.05, 0.5)]

    Upsampling and downsampling define the method used for interpolation of the data on non-natural scales. E.g. resolution of Sentinel-2 data (R,G,B and NIR bands) is 10 meters but in some occasions you would want to look at the data with higher scale (e.g. at 1 m pixel resolution) or lower scale (e.g. 1000 m pixel resolution). 
    A default option is "nearest neighbour", which is best for performance. "Bicubic" is often nicer  on higher scales.
    Note that the data are always exactly the same - it is just the interpolation method.

    An example of the NDVI image of the field:


    True color pansharpening can be implemented in Custom script in the following way:

    weight = (B04 + B03 + B02 * 0.4) / 2.4;
    if (weight == 0) {
      return [0, 0, 0];
    ratio = B08/weight * 2.5;
    return [B04*ratio, B03*ratio, B02*ratio];

    If one wants to pansharpen just RED band, it goes along the similar way:

    weight = (B04 + B03 + B02 * 0.4) / 2.4;
    if (weight == 0) {
      return [0, 0, 0];
    ratio = B08/weight * 2.5;
    return [B04*ratio];

    The Landsat Collection 1 Level-1 Quality Assessment (QA) 16-bit band, as defined at, contains unsigned integers that represent bit-packed combinations of surface, atmospheric, and sensor conditions that can affect the overall usefulness of a given pixel.

    Designated fill, terrain occlusion and cloud values represent if a condition exists:

    - 0 = This condition does not exist
    - 1 = This condition exists

    Radiometric saturation represent how many bands contain saturation:

    - 0 = No bands contain saturation
    - 1 = 1-2 bands contain saturation
    - 2 = 3-4 bands contain saturation
    - 3 = 5 or more bands contain saturation

    Cloud confidence, cloud shadow confidence, snow ice confidence and cirrus confidence represent levels of confidence that a condition exists:

    - 0 = “Not Determined” = Algorithm did not determine the status of this condition / "No" = This condition does not exist
    - 1 = “Low” = Algorithm has low to no confidence that this condition exists (0-33 percent confidence)
    - 2 = “Medium” = Algorithm has medium confidence that this condition exists (34-66 percent confidence)
    - 3 = “High” = Algorithm has high confidence that this condition exists (67-100 percent confidence

    These values can be obtained using utility function named *decodeLs8Qa*. The function returns a dictionary of all conditions, where each condition contains an extracted value. Here are examples how to use extracted values in evalScript:

    - evalScript = "return [decodeLs8Qa(BQA).cloud];";
    - evalScript = "return [decodeLs8Qa(BQA).designatedFill];";
    - evalScript = "return [decodeLs8Qa(BQA).occlusion];";
    - evalScript = "return [decodeLs8Qa(BQA).radiometricSaturation * 0.33];";
    - evalScript = "return [decodeLs8Qa(BQA).cloudConfidence * 0.33];";
    - evalScript = "return [decodeLs8Qa(BQA).cloudShadowConfidence * 0.33];";
    - evalScript = "return [decodeLs8Qa(BQA).snowIceConfidence * 0.33];";
    - evalScript = "return [decodeLs8Qa(BQA).cirrusConfidence * 0.33];";

    Often our users would like to get all available dates for specific area of interest (e.g. agriculture field) together with cloud coverage. The basic cloud coverage meta-data that we provide through our services is based on scene meta-data and is valid for 100km x 100km area, which is often not really useful if you are looking at one hectare field.

    What we recommend to do in this case is:

    1. Create a new layer configuring it to show cloud data. Make sure you output actual cloud values (e.g. 1=cloud, 0=not cloud) rather than cloud mask as an image (e.g. red=cloud, transparent=no cloud)..

    2. You can use one of several cloud detection options, such as:

    Or you define some of your own. For this exercise we will use L2A scene classification. The custom script would look something along the lines:

    switch (SCL) {
      // No Data (Missing data)    
      case 0: return [0];
      // Saturated or defective pixel   
      case 1: return [0];
      // Cloud shadows
      case 3: return [0];
      // Cloud medium probability
      case 8: return [1];    
      // Cloud high probability 
      case 9: return [1];
      // Thin cirrus 
      case 10: return [1];
      default : return [0];

    3.  Use Statistical API to query the cloud layer values over specified time range (e.g. 2017-01-01/2017-12-31) over your area of interest specified as GEOMETRY parameter.

    4. Output of the service will give you array of all dates along with mean value of "cloud" for each of the dates. Mean value "0" means there are no clouds, "1" fully covered, "0.7" 70% covered.

    To avoid problems of negative values in GeoTiff format, we have integrated DEM in a way that:

    • elevation above the sea level is stored as it is (e.g. 0-8.848 meters)
    • elevation bellow sea level is stored from 65535 downward (e.g. "-10 meters" is stored as 65525)

    To implement your own visualization, you can write a script along the following ways, e.g. "terrain if sea level rises for 2 meters":

    if (DEM >= 32768) {
      elevation = DEM - 65535.0;
    else {
      elevation = DEM;
    if (elevation > 2.0) {
      return [0,0,1];
    else {
      return [elevation/1000,elevation/1000,elevation/1000];

    Image Download and Custom Legends

    You can turn off the logo in Configuration Utility - just open "Instance configuration" and uncheck "Show logo":

    A legend can be added to the exported image by turning on the option "Show legend" when exporting an image.

    A legend may be defined in the advanced layer editor.

    Add the "legend" object in the parent “styles”. A legend is specified as JSON object that must have a property named "type" with value "continuous" or "discrete", depending on a legend type. A continuous legend also needs properties "minPosition" and "maxPosition" of a floating point type, and an array that contains stop points of a gradient. Each point must have a position of a floating point type and a color in rgb hexadecimal format. A color can also be specified using rgb function that accepts percentage values for rgb triplet, just like in CSS language. A point can optionally have a label. Here is a JSON object example of a continuous legend and the legend itself:

      "type": "continuous",
      "minPosition": 0.0,
      "maxPosition": 1.05,
      "gradients": [
        { "position": 0, "color": "rgb(0%,0%,0%)" },
        { "position": 0.05, "color": "rgb(0%,0%,0%)", "label": "- 1.0" },
        { "position": 0.050001, "color": "rgb(75%,75%,75%)" },
        { "position": 0.1, "color": "rgb(75%,75%,75%)" },
        { "position": 0.10001, "color": "rgb(86%,86%,86%)" },
        { "position": 0.15, "color": "rgb(86%,86%,86%)" },
        { "position": 0.150001, "color": "rgb(100%,100%,88%)" },
        { "position": 0.2, "color": "rgb(100%,100%,88%)", "label": "0.0" },
        { "position": 0.20001, "color": "rgb(100%,98%,80%)" },
        { "position": 0.25, "color": "rgb(100%,98%,80%)" },
        { "position": 0.250001, "color": "rgb(93%,91%,71%)" },
        { "position": 0.3, "color": "rgb(93%,91%,71%)" },
        { "position": 0.30001, "color": "rgb(87%,85%,61%)" },
        { "position": 0.35, "color": "rgb(87%,85%,61%)" },
        { "position": 0.350001, "color": "rgb(80%,78%,51%)" },
        { "position": 0.4, "color": "rgb(80%,78%,51%)" },
        { "position": 0.40001, "color": "rgb(74%,72%,42%)" },
        { "position": 0.45, "color": "rgb(74%,72%,42%)" },
        { "position": 0.450001, "color": "rgb(69%,76%,38%)" },
        { "position": 0.5, "color": "rgb(69%,76%,38%)" },
        { "position": 0.50001, "color": "rgb(64%,80%,35%)" },
        { "position": 0.55, "color": "rgb(64%,80%,35%)" },
        { "position": 0.550001, "color": "rgb(57%,75%,32%)" },
        { "position": 0.6, "color": "rgb(57%,75%,32%)", "label": "0.2" },
        { "position": 0.60001, "color": "rgb(50%,70%,28%)" },
        { "position": 0.65, "color": "rgb(50%,70%,28%)" },
        { "position": 0.650001, "color": "rgb(44%,64%,25%)" },
        { "position": 0.7, "color": "rgb(44%,64%,25%)" },
        { "position": 0.70001, "color": "rgb(38%,59%,21%)" },
        { "position": 0.75, "color": "rgb(38%,59%,21%)" },
        { "position": 0.750001, "color": "rgb(31%,54%,18%)" },
        { "position": 0.8, "color": "rgb(31%,54%,18%)" },
        { "position": 0.80001, "color": "rgb(25%,49%,14%)" },
        { "position": 0.85, "color": "rgb(25%,49%,14%)" },
        { "position": 0.850001, "color": "rgb(19%,43%,11%)" },
        { "position": 0.9, "color": "rgb(19%,43%,11%)" },
        { "position": 0.90001, "color": "rgb(13%,38%,7%)" },
        { "position": 0.95, "color": "rgb(13%,38%,7%)" },
        { "position": 0.950001, "color": "rgb(6%,33%,4%)" },
        { "position": 0.990001, "color": "rgb(6%,33%,4%)" },
        { "position": 1.0, "color": "rgb(0%,27%,0%)", "label": "0.6" },
        { "position": 1.05, "color": "rgb(0%,27%,0%)" }

    A discrete legend must have an array of objects that have a color and label. Here is a JSON object example of a discrete legend and the legend itself:

             "label":"No Data (Missing data)"
             "label":"Saturated or defective pixel"
             "label":"Dark features / Shadows "
             "label":"Cloud shadows"
             "label":"Cloud medium probability"
             "label":"Cloud high probability"
             "label":"Thin cirrus"
             "label":"Snow or ice"

    Legends are accessible at{instanceId}?service=WMS&request=GetLegendGraphic&layer={layer}&height={height}&width={width}, where height and/or width can be omitted.

    You can add a parameter GEOMETRY as in this example:<INSTANCE_ID>?SERVICE=WMS&REQUEST=GetMap&VERSION=1.3.0&LAYERS=TRUE_COLOR&MAXCC=20&WIDTH=640&HEIGHT=640&CRS=EPSG:4326
    -7.877244 38.546511,
    -7.876377 38.547818,
    -7.871950 38.546125,
    -7.872611 38.545023,
    -7.871241 38.544475,
    -7.869831 38.544560,
    -7.866011 38.550445,
    -7.872323 38.552895,
    -7.874112 38.551451,
    -7.877110 38.552537,
    -7.878791 38.552976,
    -7.879413 38.553099,
    -7.880600 38.553320,
    -7.881314 38.553126,
    -7.882678 38.552762,
    -7.883951 38.552667,
    -7.885064 38.552160,
    -7.885370 38.549346,
    -7.877244 38.546511))

    It is recommended to simplify geometry before passing it as a parameter to avoid exceeding maximum number of characters in URL.

    If one wants to have a transparent background outside of the clipped geometry, he can use "FORMAT=image/png&TRANSPARENT=1" parameters in the call. Do note however that png images are larger in size and will therefore take longer to load.

    Projections depend on the use case, however since Sentinel-2 data is originally provided in the UTM projection this is also a good choice for export. For larger areas spanning multiple UTM zones a more global projection is preferable, such as Web Mercator (EPSG:3857) or WGS84 (EPSG:4326).

    Read about the available output formats here.

    WMS, OGC and API

    The list of the available standard OGC URL parameters are available here and the advanced URL parameters are available here.

    In case you would like to get point values at some location (e.g. reflectance, NDVI, etc.) you can use the GetFeatureInfo request (e.g. "Identify features" or "feature info" in various GIS applications), e.g:<INSTANCE_ID>?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&I=0&J=0&QUERY_LAYERS=NDVI&INFO_FORMAT=application/json&BBOX=38.55105530425345,-7.883667078518689,38.55269383803389,-7.885252872445627&CRS=EPSG:4326&MAXCC=100&WIDTH=1&HEIGHT=1&TIME=2017-03-16

    Check also Statistical API.

    Use Sentinel Hub WFS request and retrieve all relevant geometries for given bounding box and time frame. From the response gather the unique dates. For each date, construct a WCS request to retrieve the image.
    See the code example bellow.

        // using Sentinel Hub OGC web services -
        // config
        window.layerName = '1_NATURAL_COLOR';
        window.from = '2015-01-01'; = '2017-04-20';
        window.bbox = '-410925.4640611076,4891969.810251283,-391357.58482010243,4911537.689492286';
        window.maxFeatures = 100; // 100 is max
        let images = [];
        let url = `${window.SENTINEL_HUB_INSTANCE_ID}
        (async () => {
            // retrieving
            // relevant geometries/images in bbox at time from-to
            // Sentinel Hub - WFS request -
            try {
                let response = await fetch(url);
                let data = await response.json();
                relevantGeometries = data;
                return data;
            } catch (e) {
                throw new Error('There was an error fetching the list of geometries from WFS service.\nDid you 
                                substitute your SENTINEL_HUB_INSTANCE_ID?');
        })().then(geometries => {
            // parsing
            // relevant geometries -> all relevant dates
            if(geometries.features === undefined) geometries.features = []
            let dates = new Set();
            geometries.features.forEach(value => {
            return Array.from(dates);            
        }).then(dates => {
            // mapping
            // dates -> image url
            // images available via WCS request -
            dates.forEach(date => {
                let niceName = `${window.layerName} from ${date}.tiff`;
                niceName = encodeURIComponent(niceName);
                let imageUrl = `${window.SENTINEL_HUB_INSTANCE_ID}
        let shout = value => {
            console.log('Images', value);

    Images are ordered by “Mosaic order” priority (see Configuration Utility, can be set for each layer; you can also set this in a parameter). You can choose either to have most recent on top or least cloud coverage. You should also take into account “maximum cloud coverage” parameter. 
    In case you want to get the most recent images acquired, you should set maximum cloud coverage to 100% and priority to “most recent”

    OGC consortium specifications for WMS, WFS, WCS, … services define the coordinate axis order. Older OGC service specifications assumed "X, Y" order for all coordinate reference systems (CRSs), even for WGS84 (EPSG:4326), while newer OGC service specifications obey the axis orders defined by the CRS's, not assuming "X, Y" order anymore. 

    Sinergise services conform to the standards definitions. The WGS84 axis order are thus version dependent:

    - WMS:
       - version 1.1.1: longitude, latitude
       - version 1.3.0: latitude, longitude
    - WFS:
       - version 1.0.0: longitude, latitude
       - version 2.0.0: latitude, longitude
    - WCS:
       - version 1.0.0: longitude, latitude

    The user should always request a specific version of OGC services by providing and explicit "VERSION" parameter in the URL.

    You can use rjson R package and then convert the JSON object into an R object as in the following code snippets:

    loadFisResponse <- function(fisQuery) {
        return rjson::fromJSON(paste(readLines(fis_query), colapse = ""))
    getDates <- function(fisResponse) {
        numberOfDates <- length(fisResponse[[1]])
        datesVector <- rep("", numberOfDates)
        for (listIndex in 1:numberOfDates) {
            datesVector[listIndex] <- fisResponse[[1]][[listIndex]]$date
    makeHistogram <- function(fisResponse, itemIndex) {
        h <- fisResponse[[1]][[itemIndex]]$histogram
        numberOfBins <- length(h$bins)
        counts = rep(0, numberOfBins)
        values = rep(0, numberOfBins)
        for (i in 1:numberOfBins) {
            counts[i] <- h$bins[[i]]$count
            values[i] <- h$bins[[i]]$value
        return(data.frame(values, counts))
    getBasicStats <- function(fisResponse, itemIndex) {
        stats <- fisResponse[[1]][[itemIndex]]$basicStats
        minValue <- stats$min
        maxValue <- stats$max
        meanValue <- stats$mean
        standardDeviation <- stats$stDev
        return(data.frame(minValue, maxValue, meanValue, standardDeviation))
    getNumberOfDates <- function(fisResponse) {

    The fisResponse object is expected to be a nested list that reflects the output format specified under FIS documentation.

    This answer is a summarized and harmonized description related to this forum thread. We will be updating the answer in line with users' feedback so that it contains a consistent set of information.

    End of June we will set S2 L1C bucket as “Requester pays” similarly as it is for S2 L2A and S1 GRD. This move is required to allow further increase of the shared data - for continuation of Sentinel-2 L1C coverage, to accommodate global rollout of Sentinel-2 L2A and to host European and then global Sentinel-2 analysis ready mosaics.

    How might this affect your workflow:

    1. If you are using the data within AWS EU (Frankfurt) region using S3 protocol, there will be practically no change. There will be some very small additional charge incurred to your account, related to “GET, SELECT and all other Requests”, currently at 0.43$ per 1 million requests.
    2. If you are using the data within any other AWS region using S3 protocol, there will be a small data transfer charge incurred to your account - "Data transfer OUT from Amazon EC2 To Another AWS region", currently at 0.02 USD per GB. You can avoid this by setting up part (or all) of your processing to AWS EU (Frankfurt) region.
    3. If you are using the data within AWS using HTTP protocol, you will need to sign requests (more info here). You will find examples on how to do it here. We will also upgrade our sentinelhub-py python libraries to work with S3 data soon (by mid of May latest) to make it easier for you.
    4. If you are using data outside of AWS, you should consider setting up AWS instance within EU-1 region. There is free tier available ( and you might be applicable for AWS research credits ( Alternatively see this thread on how it is possible to access data directly over Internet. Note that there will be a small charge for this as well "Data transfer OUT from Amazon EC2 To Internet", currently at 0.05-0.09 USD per GB.

    Note that whichever category you fall into above, you will need to make changes to your code to continue to access Sentinel-2 data on AWS. In most cases, it’s as simple as adding a flag to your object request.

    As there are several web applications out there making use of Sentinel meta-data, we have decided to make some of these data available over HTTP permanently:

    • L1C and L2A tiles
      • readme.html
      • preview.jpg
      • tileInfo.json
      • productInfo.json
      • metadata.xml
    • L1C and L2A products
      • readme.html
      • metadata.xml
      • productInfo.json

    In case you believe we should make some other meta-data available in a similar manner, describe the need in the thread bellow.

    We understand that this change might be an inconvenience to some users. However, the goal of this experiment is to discover how best to stage data for analysis and processing in the cloud. When the Sentinel Public Dataset was established two years ago, getting hold of Sentinel imagery was quite a challenge. It was distributed in unwieldy chunks and Copernicus SciHub had trouble managing the demand. And there was no other place to get it. At that time, we made a decision to make the data available as easily as possible and as openly as possible. Things are changing now, with the collaborative ground segment running, four DIAS-es coming in a few months, and data generally being more easily accessible. So we believe the time is now right to go back to original purpose – experimenting with how best to stage data for analysis in the cloud.

    All Sentinel Hub services are available using both HTTP and HTTPS protocols.

    To prevent overloading the system and to improve user experience, we have a rate limiting system in place. Find more info about it here.
    In case you need higher limit, contact support.

    Integrate Data into GIS and Web applications

    1. Go to 
    2. Sign up and login to Canvas.
    3. Click on WMS Services in the left menu as shown below:

    4. Click Add WMS Layer as shown below:

    5. Enter the WMS Service information for Sentinal in the URL field  

    6. Go to Projects, and click the Add Project Button as show below:

    7. In the Project you created above, click the Maps button as shown below:

    8. Click the Add Map button as shown below:

    9. In the left menu of the new map, expand the WMS layer you created in step 4 above. Toggle the desired layer(s). Below, we are adding the NDVI layer.

    10. Define the Geometry Area

          There are two method you can use to define a Geometry Area:

          1. A data layer
          2. Draw a Polygon or Rectange area

    While there are some simple use-cases in which you might wish to draw an area, in most cases you will be using a data layer.  
    Below, we are using a data layer of the state of Rhode Island.

    11. Click the settings icon on the NDVI Layer you created in Step 9 above. Select ‘Geometry’ from the menu as shown below:

    12. Select the Geometry Area
          a.    For a data layer (such as we are using), select Custom as the Geometry Area
          b.    For a polygon you have created via the free-hand toolbar, select Polygon

    13. Click Save and then click the Save button for your map. 

    14. Congratulations! Your map is now ready.

    1. Configure your Instance in Configuration Utility.
    2. Click "VIEW IN PLAYGROUND" button.
    3. Click  button at the top right corner to open snippet tool.
    4. Select the Google Maps maps library, type your Google Maps Api key and copy the code generated for the configured visualization.

    Figure 1: Snippet tool is accessible in Sentinel Playground if it's opened from Configuration Utility. Before integration, you must enter your Google Maps API key.

    1. Configure your Instance in Configuration Utility.
    2. Click "VIEW IN PLAYGROUND" button.
    3. Click  button at the top right corner to open snippet tool.
    4. Select the Leaflet maps library and copy the code generated for the configured visualization.

    Figure 1: Snippet tool is accessible in Sentinel Playground if it's opened from Configuration Utility

    1. Configure your Instance in Configuration Utility.
    2. Click "VIEW IN PLAYGROUND" button.
    3. Click  button at the top right corner.
    4. Select the OpenLayers maps library and copy the code generated for the configured visualization.

    Figure 1: Snippet tool is accessible in Sentinel Playground if it's opened from 
    Configuration Utility

    In some cases ArcMap turns on all layers and calls WMS. Sentinel Hub WMS service does not support visualisation of many layers at the same time. We suggest you turn off all layers and turn them on one by one.

    If you get the following error:

    Turn off all layers and turn them on one by one:

    Bring Your Own Data

    The requirements are:

    • that data are in cloud optimized geotiff (COG), with each band in a single file.
    • the internal tile size must be equal across all overview levels (including the full resolution source)
    • the projection needs to be one of: WGS84 (EPSG:4326), WebMercator (EPGS:3857), or any UTM zone (EPSG:32601-32660, 32701-32760).

    Bands can have different resolutions.

    For best performance we recommend the following setting for COGs. Deflate compressed with 1024x1024 pixel internal tiling at full resolution and on overview levels. This can be generated using GDAL, for example, with the following commands:

          gdal_translate -of GTIFF input.tif intermediate.tif

    (If your input data has nodata values add them to this command using: -a_nodata NO_DATA_VALUE, e.g. for zero: -a_nodata 0 and the full command: gdal_translate -of GTIFF -a_nodata 0 input.tif intermediate.tif)

          gdaladdo -r average --config GDAL_TIFF_OVR_BLOCKSIZE 1024 intermediate.tif 2 4 8 16 32

    (The number of overview levels you need depends on your source data. A good rule of thumb is to have as many overview levels as necessary for the entire source image to fit on one 1024x1024 tile).

          gdal_translate -co TILED=YES -co COPY_SRC_OVERVIEWS=YES --config GDAL_TIFF_OVR_BLOCKSIZE 1024 -co BLOCKXSIZE=1024 -co BLOCKYSIZE=1024 -co COMPRESS=DEFLATE intermediate.tif output.tif

    NOTE: for many types of data adding a predictor can further reduce the file size. It is best you test this on your own data, to enable the predictor add -co PREDICTOR=2 to the above command.

    Once the commands finish you can delete the intermediate.tif file.

    For more information about each command see the GDAL documentation:

    Sentinel Hub does not keep any copies of your own data. During the process of ingestion, we will read each file once to establish the index. Index will be stored on our side until you decide to remove the data from Sentinel Hub. Whenever a request will come, we will read the relevant parts of the file, in order to provide results, keeping it in the memory. Results are streamed to the user and memory contents are discarded. In no step of this process is any data stored as a file, not even temporarily.

    Once you decide to remove the data, we will delete all information we have about it.