Tasking API
Planet's Tasking API is a programmatic interface that enables customers to manage and request high-resolution imagery collection in an efficient and automated way. With the Tasking API, customers can:
- Create, edit, and cancel SkySat Tasking Orders
- Get the status of their order and check the collection progress
- View the metadata on the images tasked in attempting to fulfill their order
- Acquire high-resolution imagery from archive
Key concepts
Tasking orders follow a defined process from order creation to order fulfillment to imagery delivery. This section describes the steps and the language used to describe the process and timing of imagery collection and delivery. Planet operates in Universal Time Coordinated (UTC).

Tasking basics
- Order Time: This is when a customer submits an order for imagery.
- Scheduled Time: The time at which the order is accepted and slotted into a satellite’s schedule for collection.
- Collection Time: This is the time at which the image is captured.
- Responsiveness: The end to end time from order entry to delivery.
- Reaction Time: the time between a customer entering a tasking order and collection time.
- Latency Time: The time between collection time and delivery (standard or fast track)
- Standard Delivery: The standard latency for imagery delivery to customers that place order; deliver according to SLA not as soon as data is ready.
- Fast Track Delivery: Expedited delivery, less Latency Time, for imagery delivery as soon as data is ready.
- Archive Time (aka Archive Hold): The amount of time between when an image is delivered to a customer and publication to the archive, where it becomes available for other customers to purchase.
- Archive Publication: Point in time that an image is published to the archive and available to anyone with access to the SkySat archive.
The Archive Publication feature is available to all SkySat archive customers. Customers can choose to set the duration of their Archive Hold from 0 to 30 days. Archive Hold is measured from the date/time of image capture to Archive Publication.
The Planet Tasking API is a REST based API, which can be integrated into any service, regardless of the language used.
Authentication
The Planet API uses Basic HTTP Authentication and requires that you have a Planet API key. To obtain an API key for Planet's high-resolution tasking, please contact a Planet sales representative.
Once you have an API key, it should be added into the headers of any request made to the Tasking API endpoints. If using curl then the following would be an example of this:
--header 'authorization: api-key $PL_API_KEY'
An example of Basic HTTP Authentication with Python is included below:
import os
# import os module to access enviornmental modules
import requests
from requests.auth import HTTPBasicAuth
# import helper functions to make Basic request to Planet API
PLANET_API_KEY = os.getenv('PL_API_KEY')
# Setup the API Key from the `PL_API_KEY` environment variable
BASE_URL = 'https://api.planet.com/tasking/v2/orders/'
if PLANET_API_KEY is None:
PLANET_API_KEY = '12345'
#pass in your API key
auth = HTTPBasicAuth(PLANET_API_KEY, '')
# HTTPBasicAuth() wants a username & password; you can pass an empty string for the password
res = requests.get(url=BASE_URL, auth=auth)
print(res.status_code)
# make a request to the Tasking API and test response
Formatting
All requests and responses use the JSON format, and uses snake_case
as the naming convention.
Headers
The only header, apart from the Authorization header as mentioned above, that is required is the content-type, which should look like this:
--header 'Content-Type: application/json'
GeoJSON
All the geographical coordinate definitions in the Tasking API follow the GeoJson format
Version
The current version of the API can be found via the url https://api.planet.com/tasking/v2/version.txt
Types of tasking
The API provides three primary types of tasking.
- Flexible tasking - provides dynamic scheduling of collects and allows more control over resulting image quality
- Assured tasking - grants ability to select specific time of interest of tasking
- Archive tasking - offers access to high-resolution imagery captured in the past
Creating Tasking Order
The creation of an order via the Tasking API is done by sending a POST request to the Tasking API tasking/v2/orders
endpoint. The creation of Tasking Order can be as simple as the following request example:
curl --request POST --url 'https://api.planet.com/tasking/v2/orders/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'name': 'Order 01',
'geometry': {
'type': 'Point',
'coordinates': [
149.44135,
28.49240
]
}
}
When the PL-Number and Product are not defined in the order POST request, then the Tasking API service will select the default values that are defined for the given api-key. In the majority of cases this will be sufficient and thus the PL-Number and Product do not need to be defined. If a different PL-Number and/or product are to be chosen, then these can simply be defined as part of the order payload:
{
"name": "Order 01",
"geometry": {
"type": "Point",
"coordinates": [149.44135, 28.4924]
},
"pl_number": "$PL_CONTRACT_NUMBER",
"product": "one_time_tasking"
}
The response will contain the UUID that has been generated to identify the newly created Tasking Order, as well as any geometry created and other values related to the Tasking Order:
{
"id": "9d79b9ba-efa3-4e6d-bc08-407b545875a1",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[149.415829, 28.469843],
[149.466885, 28.469843],
[149.466896, 28.514958],
[149.415818, 28.514958],
[149.415829, 28.469843]
]
]
},
"original_geometry": {
"type": "Point",
"coordinates": [149.441357, 28.492403]
},
"order_type": "IMAGE",
"sat_elevation_angle_min": 60.0,
"sat_elevation_angle_max": 90.0,
"start_time": "2020-03-23T12:26:35.820963Z",
"end_time": "2020-04-22T12:26:35.820963Z",
"n_stereo_pov": null,
"is_cancellable": false,
"cancellable_until": "2021-08-05T10:18:00.000000Z",
"requested_sqkm": 25.0,
"created_time": "2020-03-23T12:26:36.137220Z",
"updated_time": "2020-03-23T12:26:36.137259Z",
"name": "test_order_426",
"created_by": "a.user@a.fake.email.address.com",
"status": "RECEIVED",
"fulfilled_sqkm": 0.0,
"capture_status_published_count": 0,
"capture_assessment_success_count": 0,
"capture_assessment_invalid_count": 0,
"scheduling_type": "FLEXIBLE",
"rrule": null,
"exclusivity_days": 0,
"next_planned_acquisition_time": null,
"last_acquired_time": null,
"imaging_window": null
}
Tasking with strips
The previous example showed how to create a Point Tasking Order, which takes the provided geo-coordinates and generates a 5x5 km square around that point, giving an overall area of 25 km2.
If you have two points geographically close to each other that need to be imaged, or require a longer (but not wider) area to be imaged, then defining a Strip Tasking Order would be more suitable. The difference is simple in that instead of providing a GEoJSON Point
in the Tasking Order payload, instead a LineString
is provided. For example:
curl --request POST --url 'https://api.planet.com/tasking/v2/orders/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'name': 'Order 01',
'geometry': {
'type': 'LineString',
'coordinates': [
[
10.92041015625,
48.91527985344383
],
[
10.78857421875,
49.0738659012854
]
]
}
}
Strip Tasking Orders have a fixed width of 5 km and a minimum length of 6 km and a maximum length of 100 km.
Area orders can only be created as flexible tasking orders. Therefore, the creation, editing and deletion of area orders follows flexible tasking orders.
Area orders
The creation of an Area order requires a GeoJSON object with a given type
of "Polygon" and an array of coordinates representing the polygon that will comprise the area that you want to be captured.
The area, measured in KM2, of the provided polygon should be less than your maximum allowed KM2 for a single Tasking Order.
For assistance in the creation and validation of GeoJSON polygons you can find many resources on the internet, for example https://geojson.io/.
curl --request POST --url 'https://api.planet.com/tasking/v2/orders/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'name': 'Area Order 01',
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[
-111.02062225341797,
39.58637603706183
],
[
-110.9095573425293,
39.58637603706183
],
[
-110.9095573425293,
39.670992062375056
],
[
-111.02062225341797,
39.670992062375056
],
[
-111.02062225341797,
39.58637603706183
]
]
]
}
}
The response is much the same as a flexible orders too.
Retrieving your Tasking Orders
Once you have created your Tasking Order, you can check up on it and any other Tasking Orders you may have created by performing a GET request on the same /orders
endpoint that you used to create your Tasking Orders:
curl --request GET \
--url https://api.planet.com/tasking/v2/orders/ \
--header 'Authorization: api-key $PL_API_KEY' \
--header 'Content-Type: application/json'
If you want to retrieve a specific Tasking Order, you would simply append the ID of the Tasking Order to the URL, e.g. /orders/some_UUID_number
Filtering
In the event that you have multiple Tasking Orders, the /orders
endpoint provides filtering and pagination to help manage the response payload. Through filtering you can ensure that only those Tasking Orders that you want to see are returned. Tasking Orders can be filtered by created, start and end times, name and many other values (for a full list of available parameters see: https://developers.planet.com/docs/tasking/reference/#operation/v2_orders_list)
Below is an example of request all Tasking Orders that have a name containing a given string and that were created after a particular date. Note that the created date must be a correctly formatted date/time value of the type "YYYY-mm-ddThh:mm:ssZ" and that all time are in UTC:
curl --request GET \
--url 'https://api.planet.com/tasking/v2/orders/?name__icontains=test&created_time__gt=2021-01-01T23:59:59Z' \
--header 'Authorization: api-key <YOU_API_KEY>' \
--header 'Content-Type: application/json'
Tasking API provides users with flexible means to filter available records.
Filtering in the Tasking API is a part of the GET
requests made to the /orders
and /captures
endpoints. The filtering options are mostly similar for each
endpoint, so we will be concentrating on the /orders endpoint in these
examples. A full list of all the filters available can be found in the
Tasking API
reference.
Filters in the Tasking API are AND operations, which means that each filter
parameter is joined with the previous parameters to narrow down the returned
results. The following example request to the tasking/v2/orders
endpoint shows two
filters (status & name__icontains) as well as pagination and ordering rules for
the returned results:
https://api.planet.com/tasking/v2/orders/?status=FULFILLED&name__icontains=Order&limit=50&offset=0&ordering=-updated_time,-created_time
Pagination
The parameters limit
and offset
are used to define the boundaries of the response pagination. limit
defines how many results are returns per page and offset
determines the starting index of the response. Taking this into account, the following request would return 30 results per page, starting with the 10th possible result:
curl --request GET \
--url 'https://api.planet.com/tasking/v2/orders/?limit=30&offset=10' \
--header 'Authorization: api-key <YOU_API_KEY>' \
--header 'Content-Type: application/json'
The response payload will then include the key next
and previous
with the corresponding values containing URLs that will point to the next and previous page of results. The format of these URLs is the same as the original request in the above example.
Editing Tasking Order
The ability to edit an existing Tasking Order depends upon what needs to be changed as well as the current status of the Tasking Order in the system. The following table shows what can be edited and in what state. Tasking Orders in the following states FULFILLED, CANCELLED, REJECTED and EXPIRED cannot be edited :
FIELD | PENDING | IN_PROGRESS |
---|---|---|
start_time | yes | no |
end_time | yes | yes |
Rather than a POST request, an edit requires a PUT request to be made. The following command would edit the name and start time of a an existing Tasking Order. The UUID that identifies the order is including as part of the URL:
curl --request PUT --url 'https://api.planet.com/tasking/v2/orders/<ORDER_ID_GOES_HERE>' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'start_time': '2020-04-23T12:26:35Z'
}
With a response that shows the updated fields plus the other fields that can be edited:
{
"start_time": "2020-05-23T12:26:35.000000Z",
"end_time": "2020-06-23T12:26:35.000000Z"
}
Cancelling Tasking Order
Tasking Order deletion follows similar rules to editing. Tasking Orders can be deleted or cancelled only when the Tasking Order is in one of the following states: PENDING, IN_PROGRESS and RECEIVED. A Tasking Order deletion is acheived by creating a DELETE request to the tasking/v2/orders endpoint with the ID of the Tasking Order that is to be deleted:
curl --request DELETE --url 'https://api.planet.com/tasking/v2/orders/<ORDER_ID_GOES_HERE>' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json'
Note the lack of a body in the request. A successful request receives a HTTP 204 response
Charged cancellation
See the cancellation policy for more information on charged cancellations.
If the cancellation limit of a contract is reached, the cancellation of a Tasking Order will be charged.
Users must explicitly agree to a cancellation charge by providing a new query param accept_cancellation_charge=true
in the DELETE request.
curl --request DELETE --url 'https://api.planet.com/tasking/v2/orders/<ORDER_ID_GOES_HERE>?accept_cancellation_charge=true' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json'
Otherwise, the request will be rejected with a 400
status code and an error message.
To verify how many assured cancellations have been made, take the following steps:
- Retrieve all orders with status
CANCELLED
andPENDING_CANCELLATION
with a givenupdated_time
andpl_number
curl --request GET --url 'https://api.planet.com/tasking/v2/orders/?updated_time__gt=<YYYY-MM-DD>&pl_number=<REPLACE-WITH-PL-NUMBER-HERE>&status__in=CANCELLED,PENDING_CANCELLATION&scheduling_type=ASSURED"a_units=CREDITS&fields=name,cancelled_time,id,listing&limit=50&offset=0' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json'
- It's still possible for an order to change after it has been cancelled, making that order's
updated_time
later than thecancelled_time
. So for each order returned, check that thecancelled_time
is after midnight UTC of the requested day. Orders in statusPENDING_CANCELLATION
do not havecancelled_time
but they still count towards the total number of free cancellations.
Tasking Order Pricing
Users can obtain detailed pricing information for an order (created after March 2024) by using the GET /orders/:order_id/pricing
endpoint:
curl --request GET \
--url https://api.planet.com/tasking/v2/orders/<ORDER_ID_GOES_HERE>/pricing \
--header 'Authorization: api-key $PL_API_KEY' \
--header 'Content-Type: application/json'
The response provides information on how the price was calculated by specifying quota units, the determined_by
field (which can be either pricing_model
or replaced_orders
), and applied multipliers
.
Example of pricing determined by pricing_model
{
"order_id": "87c66e26-adf5-4109-85b7-2056347372ea",
"units": "SQKM",
"estimated_quota_cost": 70.48,
"determined_by": "pricing_model",
"pricing_model": {
"base_price": 70.48,
"multipliers": [
{
"name": "imaging_mode",
"value": 1.0,
"description": "single-image"
}
]
}
}
Example of pricing determined by replaced_orders
If determined_by
is replaced_orders
it means that some other orders had to be cancelled to create this order. In this case, estimated_quota_cost
is the sum of the replaced orders:
{
"order_id": "b79eaa77-8d74-4803-9dba-dbc33760021f",
"units": "SQKM",
"estimated_quota_cost": 75.0,
"determined_by": "replaced_orders",
"pricing_model": {
"base_price": 25.0,
"multipliers": [
{
"name": "imaging_mode",
"value": 1.0,
"description": "normal"
},
{
"name": "tasking_tier",
"value": 1.0,
"description": "normal"
}
]
},
"replaced_orders": [
{
"order_id": "b9635a07-ee04-4b7b-9406-222444167018",
"name": "PLANET_476-fb96f79c-a973-4815-9817-b7dd2e84c32a_240424_250424_11",
"cost": 25.0
},
{
"order_id": "acd778f0-c490-4c9b-916a-5d736db4b04f",
"name": "PLANET_475-228e2124-3d6b-477c-a3f8-b25e9a17fb40_240424_250424_11",
"cost": 25.0
},
{
"order_id": "38a34626-71a3-448b-acd5-76831b4da9c8",
"name": "PLANET_471-c607489a-8b4d-42af-86c9-54cbd3690028_240424_250424_11",
"cost": 25.0
}
]
}
Tasking Order Pricing Preview
Users can obtain detailed estimated pricing information before creating an order by using the POST /pricing/
endpoint and sending an order-like payload as the input.
The required fields for requesting the pricing are:
geometry
: a GeoJSON objectimaging_window
: ID of the imaging window (ASSURED
orders only)
All other fields are optional (see flexible tasking).
Single order estimation
curl --request POST \
--url https://api.planet.com/tasking/v2/pricing/ \
--header 'Authorization: api-key $PL_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"pl_number": "$PL_CONTRACT_NUMBER",
"product": "Assured Tasking",
"geometry": {"type":"Point","coordinates":[40.716725,64.598217]}
}'
The response is the same as for an existing order pricing (see tasking order pricing) excluding order_id
.
Multiple orders estimation (bulk)
curl --request POST \
--url https://api.planet.com/tasking/v2/pricing/ \
--header 'Authorization: api-key $PL_API_KEY' \
--header 'Content-Type: application/json' \
--data '[{
"geometry": {"type":"Point","coordinates":[40.716725,64.598217]}
},
{
"geometry": {"type":"Point","coordinates":[40.716725,64.598217]}
}]'
The response includes pricing_details
array containing pricing information for each order payload (in the same order as the orders input payload), and a total_estimated_quota_cost
, which is the sum of the estimated_quota_cost
for each order:
{
"total_estimated_quota_cost": 50.0,
"pricing_details": [
{
"units": "SQKM",
"estimated_quota_cost": 25.0,
"determined_by": "pricing_model",
"pricing_model": {
"base_price": 25.0,
"multipliers": [
{
"name": "imaging_mode",
"description": "single-image",
"value": 1.0
}
]
}
},
{
"units": "SQKM",
"estimated_quota_cost": 25.0,
"determined_by": "pricing_model",
"pricing_model": {
"base_price": 25.0,
"multipliers": [
{
"name": "imaging_mode",
"description": "single-image",
"value": 1.0
}
]
}
}
]
}
In the event of partial failures, errors are returned for the corresponding order input payload and are not included in the calculation of total_estimated_quota_cost
:
{
"total_estimated_quota_cost": 88.775,
"pricing_details": [
{
"message": {
"error": "Failed to calculate order pricing."
}
},
{
"units": "SQKM",
"estimated_quota_cost": 25.0,
"determined_by": "pricing_model",
"pricing_model": {
"base_price": 25.0,
"multipliers": [
{
"name": "imaging_mode",
"description": "single-image",
"value": 1.0
}
]
}
},
{
"units": "SQKM",
"estimated_quota_cost": 63.775,
"determined_by": "pricing_model",
"pricing_model": {
"base_price": 63.775,
"multipliers": [
{
"name": "imaging_mode",
"description": "single-image",
"value": 1.0
}
]
}
}
]
}
Bulk operations
Tasking API provides facilities for bulk order operations. Orders can be submitted, updated or cancelled in bulk. Before going into the various aspects of Bulk creation, editing and cancellation, we will first look at the different statuses that can be attributed to a bulk operation. A bulk operation can have one of the following statuses:
- PENDING : The bulk request has been received but work has yet to start on processing the payload.
- RUNNING : Work has starting on processing the payload.
- COMPLETE : The processing of the payload has finished.
Bulk Create
POSTing to the bulk endpoint allows up to 1000 Tasking Orders to be created in a single, asynchronous, request.
When putting together the bulk tasking order request you can optionally specify your own bulk tasking order ID beforehand, but it must be a UUID string otherwise it will be rejected. If no UUID is provided, one will be generated and returned as part of the response header location field (see below) This example also only creates point orders, but any order type can be created via a bulk request.
curl --request POST --url 'https://api.planet.com/tasking/v2/bulk/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
"id": "example_uuid_string",
"order_payloads": [
{
"name": "Bulk order 1",
"geometry": {
"type": "Point",
"coordinates": [32.142035, -0.487188]
}
},
{
"name": "Bulk order 2",
"geometry": {
"type": "Point",
"coordinates": [52.142035, 13.487188]
}
},
{
"name": "Bulk order 3",
"geometry": {
"type": "Point",
"coordinates": [181, 40]
}
}
]
}'
There is no payload as part the response when the request is successful, and the response code is a 202, which denotes an asynchronous response. Included in the headers of the response is a location field which contains the URL that can be used for requesting the status of bulk order which is a GET request to the same endpoint, but this time appending the UUID that is used to identify the original bulk POST request to the URL:
curl --request GET --url 'https://api.planet.com/tasking/v2/bulk/example_uuid_string' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
This time the response, when successful, will return with a response code of 200 and a JSON payload that will look similar to the following:
{
"id": "example_uuid_string",
"start_time": "2020-03-20T13:27:28.501032Z",
"end_time": "2020-03-20T13:27:30.317499Z",
"operation_type": "CREATE",
"payload_count": 3,
"status": "COMPLETE",
"processing_payload_count": 0,
"failed_payload_count": 1,
"successful_payload_count": 2
}
Note the operation_type
is set to CREATE and that the status
is COMPLETE.
In this example the two tasking orders that comprised the original bulk tasking order POST request were successfully ingested, so there is no need to go further. However, if there are any tasking orders that are still in processing or maybe even failed for some reason then a more detailed response can be requested, using the same URL as the previous GET request but with /payloads
appended to the URL:
curl --request GET --url 'https://api.planet.com/tasking/v2/bulk/example_uuid_string/payloads' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY'
This will return a list of all the payloads in the original bulk POST, with the extra provided detail:
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": "921be80b-b351-4e2b-afba-3384aa0b63e9",
"bulk_process": "BulkProcess object (d722f658-cf66-4d00-8d3c-e286d5ca77ee)",
"order_id": "493d3e9e-176d-4617-b932-d7961f60949e",
"payload": {
"name": "Bulk order 1",
"altitude": 0,
"end_time": "2020-05-30T23:00:00Z",
"geometry": {
"type": "Point",
"coordinates": [32.142035, -0.487188]
},
"start_time": "2020-04-28T00:00:00Z"
}
},
{
"id": "a1b4fd59-1b80-4fff-b670-659a64c0ba1e",
"bulk_process": "BulkProcess object (d722f658-cf66-4d00-8d3c-e286d5ca77ee)",
"order_id": "178631b4-f23e-46e6-a77b-789cc164fdbe",
"payload": {
"name": "Bulk order 2",
"altitude": 0,
"end_time": "2020-05-30T23:00:00Z",
"geometry": {
"type": "Point",
"coordinates": [32.142032, -0.487199]
},
"start_time": "2020-04-28T00:00:00Z"
}
},
{
"id": "6fdf32db-a385-4034-8e13-c6b312ce297f",
"bulk_process": "BulkProcess object (d722f658-cf66-4d00-8d3c-e286d5ca77ee)",
"payload": {
"name": "Bulk order 3",
"altitude": 0,
"end_time": "2020-05-30T23:00:00Z",
"geometry": {
"type": "Point",
"coordinates": [181, 40]
},
"start_time": "2020-04-28T00:00:00Z"
},
"error": "{\"geometry\":[\"Geometry longitude coordinate needs to be within -180.0 and 180.0\"]}"
}
]
}
Bulk Edit
The Bulk edit endpoint allows the editing of multiple Tasking Orders in a single request, negating the need to make multiple requests for multiple Tasking Orders. The request for bulk editing Tasking Orders is very much the same as the one for bulk creation, but with the inclusion of the operation_type
field, which is an optional parameter that defaults to CREATE (which is why we didn't include it in the bulk create example) but can also be set to EDIT and CANCEL (the cancel example is further down).
Things to be aware of
- This will only work for Tasking Orders that are in the system. Because of this each, Tasking Order to be edited must be identified by its ID.
- Fields that are not present in the order payloads are left alone.
- The
operation_type
must be set as EDIT - A UUID for the bulk process is optional.
- The process is asynchronous.
- The editing of Tasking Orders via bulk follow the same rules as defined here
A curl request would look similar to this:
curl --request POST --url 'https://api.planet.com/tasking/v2/bulk/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'order_payloads': [
{
'id': 'order_UUID',
'start_time': '2021-04-29T00:00:00Z'
},
{
'id': 'order_UUID_2',
'end_time': '2021-05-29T00:00:00Z'
}],
'operation_type': 'EDIT'
}'
As with the Bulk creation workflow, there is no payload as part the response when the request is successful, and the response code is a 202, which denotes an asynchronous response. Included in the headers of the response is a location field which contains the URL that can be used for requesting the status of bulk edit which is a GET request to the same endpoint, but this time appending the UUID that is used to identify the original bulk POST request to the URL:
curl --request GET --url 'https://api.planet.com/tasking/v2/bulk/example_uuid_string' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
This time the response, when successful, will return with a response code of 200 and a JSON payload that will look similar to the following:
{
"id": "5d11a1ed-4179-45f8-a9b4-65bc40c4bf64",
"start_time": "2021-03-19T14:28:51.141569Z",
"end_time": null,
"operation_type": "EDIT",
"payload_count": 2,
"status": "RUNNING",
"processing_payload_count": 2,
"failed_payload_count": 0,
"successful_payload_count": 0
}
Note that the operation_type
is EDIT, reflecting the type of the original bulk request.
Bulk Cancel
Bulk cancellation allows multiple Tasking Orders that exist in the system to be cancelled with a single POST request, with the following caveat: only Tasking Orders with the statuses PENDING and IN_PROGRESS may be cancelled
Things to be aware of
- This will only work for Tasking Orders that are in the system. Because of this each Tasking Order to be cancelled must be identified by its ID.
- The
operation_type
must be set as CANCEL - A UUID for the bulk process is optional
- The process is asynchronous
A curl request would look similar to this:
curl --request POST --url 'https://api.planet.com/tasking/v2/bulk/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'order_payloads': [
{
'id': 'order_UUID'
},
{
'id': 'order_UUID_2'
}],
'operation_type': 'CANCEL'
}'
As with the Bulk creation workflow, there is no payload as part the response when the request is successful, and the response code is a 202, which denotes an asynchronous response. Included in the headers of the response is a location field which contains the URL that can be used for requesting the status of bulk edit which is a GET request to the same endpoint, but this time appending the UUID that is used to identify the original bulk POST request to the URL:
{
"id": "7ed1516b-e65b-4886-a82d-5237b5738dd3",
"start_time": "2021-03-19T15:18:22.131747Z",
"end_time": "2021-03-19T15:18:22.850360Z",
"operation_type": "CANCEL",
"payload_count": 2,
"status": "COMPLETE",
"processing_payload_count": 0,
"failed_payload_count": 0,
"successful_payload_count": 2
}
Note that the operation_type
is CANCEL, reflecting the type of the original bulk request.
Charged cancellation
Similar to single order cancellation, bulk order cancellation can be charged if the cancellation limit of a contract is reached.
Users must explicitly agree to a cancellation charge by providing a new field accept_cancellation_charge=true
in the body POST request.
curl --request POST --url 'https://api.planet.com/tasking/v2/bulk/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'order_payloads': [
{
'id': 'order_UUID',
'accept_cancellation_charge': true
},
{
'id': 'order_UUID_2',
'accept_cancellation_charge': true
}],
'operation_type': 'CANCEL'
}'
Capture Status
Depending on the order configuration and quality specifications, there may be multiple attempts at collecting the required AoI.
Each capture of an order has a status, so that you may follow along with where that capture is at in its lifecycle to inform expectations on acquisition or when an image might be published. The diagram below outlines how captures flow through the system.

Capture status
-
Queued: The capture has been created and sent to a satellite. It will be imminently acquired and downlinked.
-
Processing: The capture has been downlinked and is in our processing pipeline.
-
Published:
- Captures are published first to the customer who ordered the image. Only other users in this user’s organization may see this collect during this archive time period.
- After the Archive Time period has elapsed the imagery is published to all customers who have purchased the SkySat archive.
-
Failed: The capture has failed to be captured or failed in processing.
Capture Status Example
To see the status of your order’s captures, you can make a GET request for captures, filtering by order id(s). You can also filter by additional capture metadata. See our API reference for more information.
Endpoint
https://api.planet.com/tasking/v2/captures/?order_id=<order-id>
Response example
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "1e0268d2-8c96-49ed-b809-eceafa563950",
"assessment": "SUCCESS",
"updated_time": "2019-09-21T23:57:43.783444Z",
"acquired_time": "2019-09-21T08:51:31.094000Z",
"published_time": "2019-09-21T23:57:43.783444Z",
"status": "PUBLISHED",
"status_description": null,
"strip_id": "s104_20190921T085131Z",
"cloud_cover": 0.16,
"item_types": [
"SkySatScene",
"SkySatCollect"
]
}
]
}
Stereo orders
The creation, editing and deletion of Stereo orders follows the same rules as normal orders with one extra field required during creation.
curl --request POST --url 'https://api.planet.com/tasking/v2/orders/' \
--header 'accept: application/json' \
--header 'authorization: api-key $PL_API_KEY' \
--header 'content-type: application/json' \
--data '{
'name': 'Stereo Order 01',
'geometry': {
'type': 'Point',
'coordinates': [
-110.974052,
39.634139
]
},
'order_type': 'STEREO',
'n_stereo_pov': '2'
}
Two field to take note of with a stereo order are the order_type field, which is defined and set to STEREO as well as the n_stereo_pov parameter. n_stereo_pov defines how many shots are taken for the stereo image can be either 2 or 3. Any other value will result in an error. Stereo captures are supported by Flexible and Assured tasking, but depend on product configuration.
Quality assessment and delivery
Tasking products come with a set of quality requirements every collected capture should match. Every collected capture is assessed to match the specified criterias in a process called quality assessment. Types of available checks include rectification quality review, target geometry coverage, cloud/haziness evaluation and manual operator review. Specific configuration of checks and threshold values are defined in the tasking product used to create an order.
A capture will be assessed as SUCCESS
if all required checks meet specification. Its order’s state will change from IN_PROGRESS
to FULFILLED
.
A capture will be assessed as INVALID
if the required specifications were not met. Order's behavior may very, see 'Retasking' below.
Retasking
When an assured product is used, there is only one opportunity to collect an image in the specified moment of time determined by user's choice of imaging window.
For flexible tasking products however, tasking will continue untill either a fulfilling capture is collected, or the end time of an order expires. Effectively, multiple captures can be collected before an order may be fulfilled.
Order's state for this time will remain IN_PROGRESS
. Publication of a fulfilling capture will transition the order into FULFILLED
state.
Edge cases
Our team works hard to provide a most predictable tasking experience. However, sometimes things do not go as anticipated and it may create edge case scenarios where tasking API behaviour may be surprizing.
Most common edge case happens when tasking order expires before the fulfilling capture is published. When this happens, the order that was 'EXPIRED' will transition immediately to 'FULFILLED' and a published capture will become available.
As part of manual review, a capture evaluated by the system may be manually reassessed, which may cause its order’s state to change. For example, a capture the system marked as SUCCESS
may be manually reviewed as INVALID
changing its order’s state from FULFILLED
to IN_PROGRESS
(or EXPIRED
). Similar order state changes would be expected for a capture marked INVALID
which was manually reviewed as a SUCCESS
. Typically any manual review happens within 24 hours of capture publish and changes to an order’s state due to manual assessment after this time are unlikely.
Standard delivery and archive
As part of Planet’s mission to make hi-res data more accessible and actionable, Tasking orders, by default, are automatically published to the SkySat Archive. However, if you have the “30-day SkySat Archive withhold” product, you can withhold orders from the SkySat Archive for up to 30 days.
If you have the “30-day SkySat Archive withhold” offering, you can request that your CSM set a number of days—up to 30—to withhold the data from the SkySat Archive. In the Order details view, you can see the number of days you’ve requested in the “Exclusivity days” field.
To derive the SkySat Archive publication date, add the number of exclusivity days to date of acquisition. If you want to calculate this from the API, take the following steps:
- Retrieve the order via the
v2/orders/{order_id}
endpoint. The response includes a field calledexclusivity_days
, which indicates the exclusivity period for captures attributed to that tasking order. - Then make a second call to
v2/captures/?order_id={order_id}&status=PUBLISHED
, which returns all captures for the given tasking order that have been published. - For each returned capture, take the date stored in the
acquired_time
field and add the number ofexclusivity_days
to it to find the date when that capture’s exclusivity period ends. For example, if theacquired_time
is 2020-10-10T12:00:00 and theexclusivity_days
value is 30, then the exclusivity period for that capture will end on 2020-11-09T12:00:00. Note thatacquired_time
is always UTC.