Subscribe PlanetScope data via sentinel-hub Python Package

Krishna G. Lodha
Rotten Grapes
Published in
8 min readFeb 27, 2024

In the age of information, satellite imagery has become an invaluable asset for various fields including environmental monitoring, agriculture, urban planning, and disaster management. With the advent of platforms like Sentinel Hub, accessing and analyzing satellite data has become more accessible than ever before. One of the key datasets available through Sentinel Hub is PlanetScope imagery, offering high-resolution images of the Earth’s surface. In this blog post, we’ll explore how you can harness the power of PlanetScope data via Sentinel Hub for a myriad of applications.

Understanding PlanetScope Data

PlanetScope is a constellation of Earth-imaging satellites operated by Planet Labs. These satellites capture high-resolution imagery of the Earth’s surface with a high frequency of revisits. The data provided by PlanetScope satellites can be instrumental in monitoring changes in landscapes, tracking deforestation, assessing agricultural health, and much more.

What is Sentinel Hub?

Sentinel Hub is a cloud-based platform that provides access to a wealth of satellite data, including imagery from the European Space Agency’s Sentinel satellites as well as data from commercial providers like Planet Labs. It offers a powerful Application Programming Interface (API) that allows users to retrieve, process, and analyze satellite imagery for various purposes.

Purpose of this blog

PlanetScope let’s you subscribe to the area of interest based on which you will receive year long data. In this blog, we’ll explore steps on how to subscribe to data and use it with sentinelhub-py package

1. Register on sentinel hub and buy planet subscription

Registering on sentinel-hub is free, but you’ll need to purchase planet satellite data depending upon in which region you are interested. Checkout pricing page here.

Planet scope pricing

Once you have paid, you’ll receive planet apikey that you can use. You’ll also need to create client_id & client_secret for your sentinel hub account

Profile -> User settings -> Create OAuth clients
Copy client id and client secret

2. Authentication API

For all Sentinel-hub APIs, we need to provide authentication, documentaion for it is available https://docs.sentinel-hub.com/api/latest/api/overview/authentication , you can checkout implementation on following link.

This will require client_id and client_secret

Planet Subscription API

Subscription APIs allow users to register AOI and based on which user can keep receiving deliveries.

3. Create Subscription

Creating subscription will require following body

{
"name": "new_farm", // name of farm
"input": {
"provider": "PLANET",
"planetApiKey": "my_planet_key", // your planet key
"bounds": {
"geometry": {
"coordinates": [
[
[
73.76473486171818,
20.033894468220993
],
[
73.76461339277836,
20.033479489960186
],
[
73.76484528802897,
20.03346911548904
],
[
73.76488945855368,
20.03314750656199
],
[
73.76520969485364,
20.033168255545192
],
[
73.76528699327051,
20.033811472656197
],
[
73.76473486171818,
20.033894468220993
]
]
],
"type": "Polygon"
}
},
"data": [
{
"itemType": "PSScene",
"harmonizeTo": "NONE",
"productBundle": "analytic_8b_sr_udm2",
"dataFilter": {
"timeRange": {
"from": "2024-01-20T00:00:00.000Z" // from when you want to get data
},
"maxCloudCoverage": 30 // Cloud coverage
}
}
]
}
}jso

Click here to see API in working

This will create subscription which is of status CREATED , to confirm this subscription, we need to hit another API

4. Confirm Subscription

Once the collection is created, you can check the parameters before buying the service, If everything is correct in body, you can then confirm it by hitting API as following

5. Get Subscription details

Once subscription is confirmed, you can get information about it any time you want by hitting following API, it will require id of your subscription

The result will look like this

Response of Get Subscription API

6. Get Subscription delivery details

Once the AOI is subscribed, it is time to see how many datasets are available from which we can capture images .

You can get all available deliver dates and ids in following API

This will spit out array of all possible datasets as following

{
"data": [
{
"id": "a1b88b9a-8910-49e9-aeef-5a4522860c3c",
"itemId": "20240225_045407_03_24c7",
"provider": "PLANET",
"created": "2024-02-26T04:45:00.442827Z",
"status": "DONE"
},
{
"id": "cd5793e3-943c-44e9-b929-fae4dc1aaa72",
"itemId": "20240225_045259_35_2415",
"provider": "PLANET",
"created": "2024-02-26T04:28:28.954795Z",
"status": "DONE"
},
{
"id": "5831d7cb-29c2-4a04-866f-4b372dc6b743",
"itemId": "20240224_045451_37_24ba",
"provider": "PLANET",
"created": "2024-02-25T04:52:11.242871Z",
"status": "DONE"
},
{
"id": "23a5048b-9e3b-44e1-b601-51de0ec372dc",
"itemId": "20240224_045453_52_24ba",
"provider": "PLANET",
"created": "2024-02-25T04:49:28.828263Z",
"status": "DONE"
}
],
"links": {
"currentToken": "0",
"@id": "https://services.sentinel-hub.com/api/v1/dataimport/subscriptions/0eadb6a5-4786-4b2d-9ba4-bc4b6776e3e5/deliveries?viewtoken=0"
}
}

7. Get Available dates via catalog API

To get all available dates of given subscription you can use

# This is script may only work with sentinelhub.__version__ >= '3.4.0'
from sentinelhub import SentinelHubCatalog, BBox, Geometry, SHConfig, CRS, DataCollection

# Credentials
config = SHConfig()
config.sh_client_id = '<your client id here>'
config.sh_client_secret = '<your client secret here>'
config.sh_base_url = 'https://services.sentinel-hub.com'

catalog = catalog = SentinelHubCatalog(config=config)

bbox = BBox(bbox=[73.76461339277891, 20.033147506151515, 73.76528699327106, 20.033894467810516], crs=CRS.WGS84)

search_iterator = catalog.search(
'byoc-<collection-id>',
bbox=bbox,
time=('2024-01-16', '2024-02-26'),
)

results = list(search_iterator)

It will give results like

{
"type": "FeatureCollection",
"features": [
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "224e30be-b8a8-4e6f-b32f-475c8fb0657a",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-25T04:54:07.033Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/224e30be-b8a8-4e6f-b32f-475c8fb0657a",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
},
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "6d49475c-0d98-4888-adae-5611bc240600",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-25T04:52:59.353Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/6d49475c-0d98-4888-adae-5611bc240600",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
},
{
"stac_version": "1.0.0",
"stac_extensions": [
"https://stac-extensions.github.io/projection/v1.0.0/schema.json"
],
"id": "38506f0e-a961-480d-95f6-241404c09b28",
"type": "Feature",
"geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC::CRS84"
}
},
"coordinates": [
[
[
73.76473486171874,
20.033894467810516
],
[
73.76461339277891,
20.03347948954971
],
[
73.7648452880295,
20.033469115078567
],
[
73.76488945855424,
20.033147506151515
],
[
73.76520969485419,
20.033168255134722
],
[
73.76528699327106,
20.033811472245713
],
[
73.76473486171874,
20.033894467810516
]
]
]
},
"bbox": [
73.76461339277891,
20.033147506151515,
73.76528699327106,
20.033894467810516
],
"properties": {
"datetime": "2024-02-24T05:32:21.174Z",
"proj:epsg": 32643,
"proj:bbox": [
370791,
2215626,
370863,
2215710
],
"proj:geometry": {
"type": "Polygon",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::32643"
}
},
"coordinates": [
[
[
370804.77704616764,
2215709.2303530485
],
[
370791.7318965648,
2215663.394317053
],
[
370815.98008184193,
2215662.066889043
],
[
370820.3374971178,
2215626.4370114915
],
[
370853.8518226744,
2215628.486143458
],
[
370862.46303212317,
2215699.6178580034
],
[
370804.77704616764,
2215709.2303530485
]
]
]
}
},
"assets": {},
"collection": "byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/",
"rel": "root",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4/items/38506f0e-a961-480d-95f6-241404c09b28",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "parent",
"type": "application/json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/collections/byoc-ece9159e-b7c0-4ef5-b79d-d55fd1fcc6e4",
"rel": "collection",
"type": "application/json"
}
]
}

],
"links": [
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search",
"rel": "self",
"type": "application/geo+json"
},
{
"href": "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search",
"rel": "next",
"type": "application/geo+json",
"title": "Next set of results",
"method": "POST",
"body": {
"next": 10
},
"merge": true
}
],
"context": {
"next": 10,
"limit": 10,
"returned": 10
}
}

In which we can see dates and IDs of available iteration, this then can be used in Process APIs to get data out of it.

8. Get Data using Process API

# This is script may only work with sentinelhub.__version__ >= '3.4.0'
from sentinelhub import SentinelHubRequest, DataCollection, MimeType, CRS, BBox, SHConfig, Geometry

# Credentials
config = SHConfig()
config.sh_client_id = '<your client id here>'
config.sh_client_secret = '<your client secret here>'
evalscript = """
//VERSION=3

function setup() {
return {
input: ["Blue", "Green", "Red"],
output: { bands: 3 }
};
}

function evaluatePixel(sample) {
return [sample.Red / 3000, sample.Green / 3000, sample.Blue / 3000];
}


"""
bbox = BBox(bbox=[73.76461339277891, 20.033147506151515, 73.76528699327106, 20.033894467810516], crs=CRS.WGS84)
geometry = Geometry(geometry={"type":"Polygon","crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:OGC::CRS84"}},"coordinates":[[[73.76473486171874,20.033894467810516],[73.76461339277891,20.03347948954971],[73.7648452880295,20.033469115078567],[73.76488945855424,20.033147506151515],[73.76520969485419,20.033168255134722],[73.76528699327106,20.033811472245713],[73.76473486171874,20.033894467810516]]]}, crs=CRS.WGS84)

request = SentinelHubRequest(
evalscript=evalscript,
input_data=[
SentinelHubRequest.input_data(
data_collection=DataCollection.define_byoc('<collection_id>'),
time_interval=('2024-02-25', '2024-02-25'),
),
],
responses=[
SentinelHubRequest.output_response('default', MimeType.JPG),
],
bbox=bbox,
geometry=geometry,
size=[512, 604.326],
config=config
)

response = request.get_data()

based on catalog data, you can fill up time_interval information.

results will look like this

True Color
NDVI

--

--