Task Lifecycle Tutorial

Read this tutorial if you are looking for a step-by-step guide on how to schedule and retrieve a collect from start to finish.

Send Feasibility Request

Send a cURL request as follows, inserting your Bearer Token, latitude, longitude, and tasking window in ISO8601 format (YYYY-MM-DDT00:00:00Z), as well as modifying any other parameters desired.

curl --request POST \
   --url https://api.canopy.umbra.space/tasking/feasibilities \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <BEARER_TOKEN>' \
     --header 'content-type: application/json' \
     --data '
{
     "imagingMode": "SPOTLIGHT",
     "spotlightConstraints": {
          "geometry": {
               "type": "Point",
               "coordinates": [
                    <LONGITUDE>,
                    <LATITUDE>
               ]
          },
          "polarization": "VV",
          "rangeResolutionMinMeters": 1,
          "multilookFactor": 1,
          "grazingAngleMinDegrees": 30,
          "grazingAngleMaxDegrees": 70,
          "targetAzimuthAngleStartDegrees": 0,
          "targetAzimuthAngleEndDegrees": 360
     },
     "windowStartAt": "<YYYY-MM-DDT00:00:00Z>",
     "windowEndAt": "<YYYY-MM-DDT00:00:00Z>"
}
'

This will return a Feasibility ID, which can be used to poll for Opportunities.

Poll for Opportunities

Insert your Bearer Token and Feasibility ID to poll for opportunities. When status transitions to COMPLETED, Opportunities list will be populated with Opportunities. If opportunities is null, resubmit step 1 with a longer time window.

curl --request GET \
     --url https://api.canopy.umbra.space/tasking/feasibilities/<FEASIBILITY_ID> \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <BEARER_TOKEN>'

An example of a successful opportunity looks as follows:

{
	"durationSec": 106.0,
	"grazingAngleEndDegrees": 41.62010781558027,
	"grazingAngleStartDegrees": 41.62947469239037,
	"groundRangeEndKm": 526.66330627147,
	"groundRangeStartKm": 525.8848195176256,
	"slantRangeEndKm": 764.1847054671697,
	"slantRangeStartKm": 761.6243772652538,
	"squintAngleEndDegrees": 135.31102583657602,
	"squintAngleStartDegrees": 45.11766881409077,
	"targetAzimuthAngleEndDegrees": 305.63160791809025,
	"targetAzimuthAngleStartDegrees": 214.67019647500493,
	"windowEndAt": "2023-02-11T21:58:07.682855+00:00",
	"windowStartAt": "2023-02-11T21:56:21.682855+00:00"
}

Create a Task using an Opportunity

To create a new Task Request that captures a specific Opportunity, copy the entire spotlightConstraints object from your Feasibility Request into the Task Request. Then copy the windowStartAt and windowEndAt from the Opportunity you'd like to use into the Task Request.

curl --request POST \
     --url https://api.canopy.umbra.space/tasking/tasks \
     --header 'accept: application/json' \
     --header 'authorization: Bearer '<BEARER_TOKEN>' \
     --header 'content-type: application/json'
    --data '
{
     "imagingMode": "SPOTLIGHT",
     "spotlightConstraints": <FEASIBLITY_SPOTLIGHT_CONSTRAINTS>,
     "windowStartAt": "<OPPORTUNITY_WINDOW_START_AT>",
     "windowEndAt": "<OPPORTUNITY_WINDOW_END_AT>",
     "taskName": "<TASK_NAME>"
}
'

This will return JSON containing a Task ID, which can be used to poll Task status updates.

Poll for Task by ID

Use the Task_ID from the previous request to poll for status updates:

curl --request GET \
     --url https://api.canopy.umbra.space/tasking/tasks/<TASK_ID> \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <BEARER_TOKEN>'

Tasks should transition to "SCHEDULED" status once they have been added to the schedule. When a Task status transitions to "DELIVERED" data from the collect is ready to be downloaded via the STAC endpoints. You will need your Task_id to complete the following step.

Retrieve Associated Collect IDs from Task

Your collect data can be downloaded once the collect status is "DELIVERED". This will generally happen 1-4 hours after the associated Task's windowEndAt has passed. In order to do that, you need to first get your Collect_id. To do so, use the following cURL request:

curl --request GET \
     --url https://api.canopy.umbra.space/tasking/tasks/<TASK_ID> \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <BEARER_TOKEN>'

The response will contain a collectIds property with the Collect IDs assocated with this Task.

Retrieve Item for data download link

Use the following cURL request to retrieve the link to your data, inserting your Organization ID, the Collect ID from the previous step, and your Bearer Token.

Your Organization ID can be retrieved by logging into Canopy and navigating to your account settings

curl --request GET \
     --url https://api.canopy.umbra.space/stac/collections/<ORGANIZATION_ID>/items/<COLLECT_ID> \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <BEARER_TOKEN>'

The STAC Item response will include pre-signed urls that allow direct download of your data. The STAC Item conforms to the Alternate Assets extension using the object key s3_signed. See below for an example response:

{
  "id": "c345090b-b20a-4d45-9ea6-2691ccefc12e",
  "assets": {
    "2023-02-21-16-12-39_UMBRA-04.tif": {
      "href": "s3://...",
      "type": "image/tiff; application=geotiff; profile=cloud-optimized",
      "created": "2023-02-21T17:59:28Z",
      "description": "GEC",
      "alternate": {
        "s3_signed": {
          "title": "S3 signed url for direct download",
          "description": "Expires at: 2023-02-22T00:06:15+00:00",
          "href": "https://..."
        }
      }
    },
    "2023-02-21-16-12-39_UMBRA-04.cphd": {
      "href": "s3://...",
      "type": "application/octet-stream",
      "created": "2023-02-21T17:59:28Z",
      "description": "CPHD",
      "alternate": {
        "s3_signed": {
          "title": "S3 signed url for direct download",
          "description": "Expires at: 2023-02-22T00:06:15+00:00",
          "href": "https://..."
        }
      }
    },
    "2023-02-21-16-12-39_UMBRA-04_SICD.nitf": {
      "href": "s3://...",
      "type": "application/octet-stream",
      "created": "2023-02-21T17:59:27Z",
      "description": "SICD",
      "alternate": {
        "s3_signed": {
          "title": "S3 signed url for direct download",
          "description": "Expires at: 2023-02-22T00:06:15+00:00",
          "href": "https://..."
        }
      }
    },
    "2023-02-21-16-12-39_UMBRA-04_SIDD.nitf": {
      "href": "s3://...",
      "type": "application/octet-stream",
      "created": "2023-02-21T17:59:28Z",
      "description": "SIDD",
      "alternate": {
        "s3_signed": {
          "title": "S3 signed url for direct download",
          "description": "Expires at: 2023-02-22T00:06:15+00:00",
          "href": "https://..."
        }
      }
    },
    "2023-02-21-16-12-39_UMBRA-04_METADATA.json": {
      "href": "s3://...",
      "type": "application/json",
      "created": "2023-02-21T17:59:28Z",
      "description": "METADATA",
      "alternate": {
        "s3_signed": {
          "title": "S3 signed url for direct download",
          "description": "Expires at: 2023-02-22T00:06:15+00:00",
          "href": "https://..."
        }
      }
    }
  },
  "links": [...],
  "geometry": {...},
  "collection": "...",
  "properties": {...}
}