STAC Support (Beta)
STAC support is currently in beta.
Planet provides an experimental STAC service at https://api.planet.com/x/data/. For details on the routes available, see the API reference. The service also hosts a generic STAC browser that can be used to view metadata on collections and items in the global catalog.
Authentication
As with other Planet APIs, the STAC services require authentication. Authentication options include:
- basic auth with an API key in the username field or
- a bearer token in an
Authorization
header.
The links generated by the service (For example, to tiles for an item) will not include your credentials by default. For convenience, you can include the ?auth=true
query string to have the service generate links that include your credentials. Other services or systems that might share the generated metadata should not use this parameter.
Planet Catalog
The Planet STAC catalog uses the Planet STAC Extension to include fields and attributes specific to Planet products. To align with STAC conventions, some fields may be similar but not identical to the equivalent field in other Planet systems. To view the differences between fields in the STAC service and other Planet APIs, see Planet STAC Extension field mapping and scope.
Item Queries
The items
endpoint for a feature collection accepts the following query parameters:
limit
- Limit the number of items returned per page. By default, 100 items are returned per page.datetime
- Filter items based on acquisition time. For date range queries, provide a/
delimited pair of formatted datetimes. For open ended ranges, use..
. For example, to get images acquired in 2020 and later, make a query likedatetime=2020-01-01T00:00:00Z/..
.bbox
- Filter items based on a geographic bounding box. Thebbox
parameter is a list of min longitude, max longitude, min latitude, max latitude values separated by commas.auth
- Include credentials in resource links. By default, credentials are not included in links.
See the API reference for more detail.
Cross-Collection Search
A basic temporal or spatial search can be performed using the item query parameters described above. The /search
endpoint can be used instead to search using additional parameters or across multiple collections. A POST
request to the /search
endpoint initiates a search. The result of a search is an item collection (as returned by the items
endpoint) with pagination links.
When posting a search, the body of the request is a JSON object with the following properties:
limit
- Limit the number of items returned. By default, 100 items are returned.collections
- A comma-delimited list of collection identifiers (or item types) to be used in the search. By default, all available collections will be searched.bbox
- Filter items based on a geographic bounding box. Thebbox
value is an array of min longitude, max longitude, min latitude, max latitude values.intersects
- Filter based on a GeoJSON geometry. Theintersects
value can be any GeoJSON geometry type.datetime
- Filter items based on acquisition time. For date range queries, provide a/
delimited pair of formatted datetimes. For open ended ranges, use..
. For example, to get images acquired in 2020 and later, include adatetime
value like"2020-01-01T00:00:00Z/.."
.ids
- Filter based on item identifiers as a list of strings.filter
- A filter using the JSON encoding of the OGC Common Query Language (CQL2). The syntax supports spatial comparisons (For example,s_intersects
), temporal comparisons (For example,t_after
), numeric comparisons (For example,>=
), logical expressions (For example,or
), and additional comparison operators (For example,in
). See below for example CQL2 searches and their Planet query equivalents.
Searches posted to the /search
endpoint can also use the auth
query parameter as described above.
Geometry intersection
The request below is equivalent to a Data API search with a GeometryFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene", "SkySatScene"],
"filter": {
"op": "s_intersects",
"args": [
{"property": "geometry"},
{
"type": "Point",
"coordinates": [-111, 45.68]
}
]
}
}'
Date range
The request below is equivalent to a Data API search with a DateRangeFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene", "SkySatScene"],
"filter": {
"op": "t_intersects",
"args": [
{"property": "updated"},
{"interval": ["2020-01-01", "2021-01-01"]}
]
}
}'
Logical filters
The request below is equivalent to a Data API search with an AndFilter
that includes a GeometryFilter
, a DateRangeFilter
, and a filter for cloud cover.
Logical operators and
, or
, and not
are supported.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "and",
"args": [
{
"op": "s_intersects",
"args": [
{"property": "geometry"},
{
"type": "Point",
"coordinates": [-111, 45.68]
}
]
},
{
"op": "t_after",
"args": [
{"property": "updated"},
{"date": "2024-07-01"}
]
},
{
"op": ">=",
"args": [
{"property": "clear_percent"},
50
]
}
]
}
}'
Comparison filters
The in
comparison operator can be used to search for items with a property value that matches a string or a number in a list.
The request below is equivalent to a Data API search with a NumberInFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "in",
"args": [
{"property": "gsd"},
[3, 6, 9]
]
}
}'
The request below is equivalent to a Data API search with a StringInFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "in",
"args": [
{"property": "satellite_id"},
["2414", "2415"]
]
}
}'
The between
operator can compare a numeric property to a range of values. The request below is equivalent to a Data API search with a RangeFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "between",
"args": [
{"property": "gsd"}, 13, 15
]
}
}'
The <
, <=
, >
, and >=
operators can also create range filters for numeric properties.
The =
and <>
operators can filter based on a numeric or string property.
Filters with the above comparison operators require a property expression as the first argument.
Asset filter
To filter for items that include a specific asset, use the asset
function in a filter. The request below is equivalent to a Data API search with a AssetFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "asset",
"args": ["analytic"]
}
}'
Permission filter
To filter for items for which the user has a specific permission, use the permission
function in a filter. The request below is equivalent to a Data API search with a PermissionFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "permission",
"args": ["assets:download"]
}
}'
Update filter
To filter for items with a specific property updated, use the updated
function in a filter. The request below is equivalent to a Data API search with a UpdateFilter
.
- CURL
curl --request POST \
-u "${PL_API_KEY}:" \
-H "Content-Type: application/json" \
--url "https://api.planet.com/x/data/search" \
-d \
'{
"limit": 10,
"collections": ["PSScene"],
"filter": {
"op": "updated",
"args": [
{"property": "ground_control"},
">",
{"date": "2020-01-01"}
]
}
}'
PySTAC
For Python scripts and applications, the PySTAC client library can access the Planet STAC service.
Configure the PySTAC client
With the PySTAC client library installed, create a client for use with the Planet STAC service.
- Python
import base64
import os
from pystac_client import Client
api_key = os.environ.get("PL_API_KEY")
assert api_key is not None, "the PL_API_KEY environment variable must be set"
# create a client using your API key
userpass = f"{api_key}:"
client = Client.open(
url="https://api.planet.com/x/data/",
headers={"Authorization": f"Basic {base64.b64encode(userpass.encode()).decode()}"},
)
Set up logging (optional)
Logging is optional but may be useful:
- Python
import logging
logging.basicConfig()
logger = logging.getLogger("pystac_client")
# optionally set to DEBUG to see API calls
logger.setLevel(logging.INFO)
Search for images
Use the PySTAC client to search for Planet data. In this example, we search for images that are at least 50% clear:
- Python
params = dict(
max_items=100,
collections="PSScene",
intersects={"type": "Point", "coordinates": [-111, 45.68]},
datetime="2024-06-01/2024-08-01",
filter={"op": ">=", "args": [{"property": "clear_percent"}, 50]},
)
search = client.search(**params)
# max of 100 items, get them all as a list
items = list(search.items_as_dicts())
Working with item properties
Planet STAC items contain properties. The example below plots the values of pl:clear_percent
using matplotlib.
- Python
from datetime import datetime
import matplotlib.pyplot as plt
clear_percents = []
dates = []
for item in items:
properties = item.get("properties", {})
clear_percents.append(properties.get("pl:clear_percent"))
dates.append(
datetime.strptime(properties.get("datetime"), "%Y-%m-%dT%H:%M:%S.%f%z")
)
plt.xlabel("Date")
plt.ylabel("Clear Percent")
plt.xticks(rotation=30)
plt.title("Two Months of Imagery")
plt.plot(dates, clear_percents, marker="o", markerfacecolor="white", linewidth=0.5)