Tasking tutorial

Read this tutorial if you are looking for a step-by-step guide on how to create a satellite tasking order, monitor its status and get data delivered from start to finish using Python SDK.

In this guide, you will learn how to:

  1. Run feasibility check for the standard priority tasking order
  2. Select a satellite pass for the assured priority tasking order
  3. Retrieve the price of the order
  4. Place the tasking order
  5. Monitor the order’s status
  6. Receive the data

The process for feasibility check and order placement differ for standard priority and assured priority tasking products. This tutorial describes the process for both of them.

Standard priority tasking product

Setting up tasking order parameters

Python SDK functions and RESTful API endpoints for creating a feasibility request, estimating price and placing tasking orders have exactly the same schema. Therefore, in this tutorial, we will first set up parameters and then call them from different functions.

You can initialise tasking order parameters like so:

from datetime import datetime
from os import getenv
 
# Set your contract ID in an environmental variable named CONTRACT_ID before running this
contract_id = getenv("CONTRACT_ID")
 
# Define the coordinates for the target location
coordinates = (-2.7783632, 53.3240764)
 
# Define the start and end dates for the feasibility analysis
date_from = datetime(2024, 5, 1)
date_to = datetime(2024, 5, 31)
 
# Specify day_night_mode (optional, defaults to "day-night")
day_night_mode = "day"
 
# Specify the tasking product
product = "standard"

Running a feasibility check

We described the concept behind the feasibility study in the Tasking feasibility page. Using Python SDK, you will need first to create a feasibility request and then retrieve the information about it.

# Call the post_feasibility function with the specified tasking order parameters
response = client.otm_v2.post_feasibility(
  coordinates=coordinates,
  date_from=date_from,
  date_to=date_to,
  day_night_mode=day_night_mode,
  product=product,
  contract_id=contract_id
)

Here is an example of the response:

{
  "bbox": [-2.7783632, 53.3240764, -2.7783632, 53.3240764],
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [-2.7783632, 53.3240764]
  },
  "properties": {
    "datetime": "2024-05-01T00:00:00+00:00/2024-05-31T23:59:59+00:00",
    "satvu:day_night_mode": "day",
    "max_cloud_cover": 30,
    "min_off_nadir": 0,
    "max_off_nadir": 45,
    "min_gsd": 3.5,
    "max_gsd": 6.8,
    "status": "pending",
    "created_at": "2024-03-28T15:58:20.823201",
    "updated_at": "2024-03-28T15:58:20.823201"
  },
  "id": "ba6c0b66-615a-4e1a-b322-a11a6a4eba31",
  "contract_id": null,
  "links": [
    {
      "href": "https://...",
      "rel": "self",
      "method": "GET",
      "body": null,
      "merge": null,
      "type": "application/json",
      "title": null
    },
    {
      "href": "https://...",
      "rel": "response",
      "method": "GET",
      "body": null,
      "merge": null,
      "type": "application/json",
      "title": null
    }
  ]
}

Now, using the id of the feasibility requests, you can check the status of it with the following query:

# Retrieve the feasibility ID
feasibility_id = response["id"]
 
# Call the get_feasibility function with feasibility_id and contract_id
feasibility_data = client.otm_v2.get_feasibility(id=feasibility_id, contract_id=contract_id)

The status field identifies the information about the tasking order feasibility. We recommend placing the tasking order only when the status is feasible.

Price estimation

We want to ensure transparent pricing of the tasking order, so we provide a function you can use to retrieve the price of your tasking order:

# Call the get_price function with the specified tasking order parameters
response = client.otm_v2.get_price(
  coordinates=coordinates,
  date_from=date_from,
  date_to=date_to,
  day_night_mode=day_night_mode,
  contract_id=contract_id
)

In the response body, you will see your original request and the price field with price of the order. This price will be deducted from your credit limit once you place an order.

Placing a tasking order

For placing a tasking order, you need to provide your order parameters to the create_order function.

# Call the create_order function with the specified tasking order parameters
response = client.otm_v2.create_order(
  coordinates=coordinates,
  date_from=date_from,
  date_to=date_to,
  day_night_mode=day_night_mode,
  contract_id=contract_id
)

This will return a JSON with the order information and order ID (id), which you can use to retrieve information about the order.

You will notice a status field in the properties object. Shortly after the initial created status the value should transition to staged. More information about statuses and tasking order is available under Tasking order.

Assured priority tasking product

Exploring available passes

As mentioned in the Tasking feasibility page, the feasibility request for the assured priority tasking product returns information about the available passes over the target.

First, let’s define assured priority tasking product parameters.

from datetime import datetime
from os import getenv
 
# Set your contract ID in an environmental variable named CONTRACT_ID before running this
contract_id = getenv("CONTRACT_ID")
 
# Define the coordinates for the target location
coordinates = (-2.7783632, 53.3240764)
 
# Define the start and end dates for the feasibility analysis
date_from = datetime(2024, 4, 1)
date_to = datetime(2024, 4, 7)
 
# Specify the tasking product
product = "assured"

Then, let’s create the feasibility request:

# Call the post_feasibility function with the specified tasking order parameters
response = client.otm_v2.post_feasibility(
  coordinates=coordinates,
  date_from=date_from,
  date_to=date_to,
  product=product,
  contract_id=contract_id
)

Once the feasibility request is processed, you can retrieve the available passes for the selected location and a timeframe:

# Retrieve the feasibility ID
feasibility_id = response['id']
 
# Call the get_feasibility_response function with feasibility_id and contract_id
feasibility_data = client.otm_v2.get_feasibility_response(id=feasibility_id, contract_id=contract_id)

Here is an example of the response:

{
  "type": "FeatureCollection",
  "features": [
    {
      "bbox": [
        -26.213044,
        67.63173,
        -26.213044,
        67.63173
      ],
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [
          -26.213044,
          67.63173
        ]
      },
      "properties": {
        "datetime": "2024-04-02T16:02:24+00:00/2024-04-02T16:44:57+00:00",
        "product": "assured",
        "created_at": "2024-03-26T15:22:47.801650",
        "updated_at": "2024-03-26T15:22:47.801650",
        "satvu:day_night_mode": "day-night",
        "max_cloud_cover": 100,
        "min_off_nadir": 2.2502104916152676,
        "max_off_nadir": 44.0818123268789,
        "min_gsd": 3.753866137463882,
        "max_gsd": 6.706020499472806,
        "min_sun_el": 22.28186477676762,
        "max_sun_el": 22.444073991687915
      },
      "id": "9800b80b-cea1-4a91-b151-9dc444b89270",
      "signature": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6IjIwMjQtMDQtMDJUMTY6MDI6MjQrMDA6MDAvMjAyNC0wNC0wMlQxNjo0NDo1NyswMDowMCIsImxvY2F0aW9uIjpbLTI2LjIxMzA0NCw2Ny42MzE3M10sImV4cCI6MTcxMTQ3ODU1MywiaXNzIjoiaHR0cHM6Ly9hcGkucWEuc2F0ZWxsaXRldnUuY29tL290bS8ifQ.8r5HlWJc9uGcHP4olzOAJDLR_yJZ7dBuJ3XJNlCuVpq0kNGS8SPVRJC2O9jua1KheCFBE5Ezir3pgeI0ImPGBA"
    },
    {...},
  ],
  "id": "d1643376-567d-4af0-93dc-a7b76eb349ca",
  "links": [
    {
      "href": "https://...",
      "rel": "self",
      "method": "GET",
      "body": null,
      "merge": false,
      "type": "application/json",
      "title": null
    },
    {
      "href": "https://...",
      "rel": "request",
      "method": "GET",
      "body": null,
      "merge": false,
      "type": "application/json",
      "title": null
    }
  ],
  "status": "feasible",
  "contract_id": "..."
}

Now using the signature value from the feasibility response, you can place an assured priority tasking order.

Price estimation

We want to ensure transparent pricing of the tasking order, so we provide an endpoint you can use to retrieve the price of your tasking order:

# Call the get_price function with the specified tasking order parameters
response = client.otm_v2.get_price(
  coordinates=coordinates,
  date_from=date_from,
  date_to=date_to,
  product=product,
  contract_id=contract_id
)

In the response body, you will see your original request and the price field with the price of the order. This price will be deducted from your credit limit once you place an order.

Placing a tasking order

To place an assured priority tasking order, only the signature value from the feasibility check step is required.

# Example of extracting signature value from the feasibility response
signature = feasibility_data['features'][0]['signature']
 
# Call the create_order function with the specified tasking order parameters
response = client.otm_v2.create_order(
  signature=signature,
  product=product,
  contract_id=contract_id
)

This will return a JSON with the order information and order ID (id), which you can use to retrieve information about the order.

You will notice a status field in the properties object. Shortly after the initial created status the value should transition to staged. More information about statuses and tasking order is available under Tasking order.

Monitoring orders

We provide a few endpoints to retrieve information about tasking orders. You can use get_order to get information about a specific tasking order:

# Retrieve the order ID
order_id = response["id"]
 
# Call the get_order function with order_id and contract_id
order_data = client.otm_v2.get_order(order_id=order_id, contract_id=contract_id)

You can also view all your orders with list_orders:

# Call the list_orders function
orders_data = client.otm_v2.list_orders(contract_id=contract_id)

Or search orders providing more advanced parameters. The following example searches orders that are placed in the specified geometry:

search_geometry = {
  "coordinates": [
    [
      [
        -8.60621344099522,
        60.63920763634644
      ],
      [
        -14.213293594801314,
        45.95851155946286
      ],
      [
        10.621928171802324,
        52.72769978027327
      ],
      [
        -8.60621344099522,
        60.63920763634644
      ]
    ]
  ],
  "type": "Polygon"
}
 
# Call the search function
orders_data = client.otm_v2.search(
  collections=["orders"],
  intersects=search_geometry,
  contract_id=contract_id
)

Once the order status has changed to fulfilled, you can download the data.

Data download

We provide a data download endpoint that requires you to specify the Order ID. When you run it, the endpoint response is actual data in bytes. You can save it as a .zip archive.

from pathlib import Path
 
# Downloading the order with order_id and contract_id provided
client.otm_v2.download_order(order_id=order_id, destdir=Path(), contract_id=contract_id)