Skip to main content

STAC Support (Beta)

info

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 like datetime=2020-01-01T00:00:00Z/...
  • bbox - Filter items based on a geographic bounding box. The bbox 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.

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. The bbox value is an array of min longitude, max longitude, min latitude, max latitude values.
  • intersects - Filter based on a GeoJSON geometry. The intersects 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 a datetime 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 --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 --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 --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 --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 --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 --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 --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 --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 --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.


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:

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:

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.

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)