1. Info
  2. Stockpile Measurement

Getting Started with the Stockpile Measurement API

This guide will walk you through the full process of accessing Stockpile Measurement data via API endpoints

About the Stockpile Measurement API

Ursa Space's Stockpile Measurement RESTful API facilitates access to volumetric measurements derived from satellite imagery. It consists of a single endpoint that supports advanced queries.Stockpile Header

Measuring Stockpiles

Before diving into the mechanics of the API, it is important to first establish a solid understanding of the underlying data. Each stockpile in Ursa Space's catalog is measured on a weekly cadence, and these volumes are aggregated by pile yard. For example, the pile yard by the name of Qingdao Pile Yard 1 includes every measurable stockpile that is bounded by the following geographic MultiPolygon WKT:

MULTIPOLYGON(((120.18650589030416 36.01824326699104, 120.1887765639092 36.01984490283745, 120.18565438770227 36.024365976176036, 120.18865492068035 36.02564323007886, 120.19279079046095 36.02122352609765, 120.20094088679329 36.02562295620739, 120.20156937680896 36.02473090586256, 120.18737766677752 36.01704710857411, 120.18650589030416 36.01824326699104)))

Every Thursday at 14:00 UTC, a new total volume is published for each pile yard, which represents the combined sum of all stockpile measurements within its boundary. It is possible for measurements of a given report week to be updated after being published, but users of the API can detect such changes using the measurement's  last_measured property. More details about this value can be found in the Measurement Schema.

API access to each individual stockpile height and volume measurement is still under development at the time of writing (April 24, 2024). Access to all raw measurements for each pile yard used in the weekly generated reports is planned.

Measurement Schema

Below is a table that describes all the fields returned by the API for a given measurement and whether they are searchable. A single Measurement instance contains the total volume of a particular pile yard for a given report week as well as some contextual information.

Fieldname Searchable Description
report_date Yes The date and time this measurement was published. This is normally Thursdays at 14:00 UTC.
pile_yard_name Yes The unique identifier of the pile yard this measurement represents.
pile_yard_polygon No The geographic boundary of the pile yard in WKT format.
total_yard_volume No The combined sum representing the total volume of all the stockpiles contained in the pile yard.
volume_units No The units of total_yard_volume. This is almost always "cubic meters".
material_type Yes The type of material stored at this pile yard.
material_density No The density of material_type.
material_density_units No The units of material_density. This is almost always "kilograms per cubic meter".
kilotons No The total weight of material measured at the pile yard. This value is calculated using total_yard_volume, volume_units, material_density, and material_density_units.
number_of_piles No The total number of stockpiles detected at the pile yard.
number_of_piles_measured No Of all the piles detected, this value represents the size of the measurable subset.
location_name Yes The name of the pile yard's location. Example: "Caofeidian".
location_type Yes A value describing the purpose of the pile yard's location. Examples: "Port", "Power Plant", etc. 
region_name Yes The region containing this pile yard. At this time a pile yard can only be a member of a single region. Example: "Pilbara".
country_name Yes The country of the pile yard.
pile_yard_operator Yes The name of the entity that operates the pile yard. Example: 
"Transnet National Ports Authority".
image_dates No A list containing the date time of each satellite image used to measure the pile yard. Each image date should be within one week of report_date.
last_measured_date Not yet A date time representing when the imagery of this pile yard was analyzed. In the event that this measurement needs to be recomputed, the value for this field will be updated accordingly.
execution_record_ids No (Reserved for internal use only at Ursa Space) The IDs of the analytic execution jobs that measured the stockpiles of this pile yard. These IDs can be used to lookup execution details stored in the stockpile_measurement_execution_records_qc STAC collection of Ursa's Analytics Results Service API. 
output_ids No Contains the ID of each volumetric stockpile measurement output from the execution jobs identified in execution_record_ids. These IDs can be used to lookup stockpile specific details stored in the stockpile_measurement_outputs_qc STAC collection of Ursa's Analytics Results Service API. Please see the Advanced Feature: Accessing Individual Stockpile Measurements section for more information.

API Request Format (GET /data)

The Stockpile Measurement RESTful API has a single endpoint retrieving data which has the following base URL:

https://platform.ursaspace.com/api/v1/smp/data

Requests to this endpoint require authentication. Please see this article to learn how to generate bearer tokens. Once a token is generated, it must be included in the Authorization header of every request using the following format:

Authorization: Bearer <token>

Every Measurement field name marked as "Searchable" in the table above can be used as an optional query parameter for filtering results. If multiple query parameters are provided, they will be applied using the AND operation. 

Query Parameter Required Description
report_date_start Yes A date time representing the lower bound of report dates to consider. Measurements with a report_date before this date will be discarded.
report_date_end Yes A date time representing the upper bound of report dates to consider. Measurements with a report_date after this date will be discarded.
pile_yard_name No Filter by pile yard.
material_type No Filter by material type.
location_name No Filter by location.
location_type No Filter by location type.
region_name No Filter by region.
country_name No Filter by country.
pile_yard_operator No Filter by operator.

API Response Format

The API response is a JSON with a single property named measurements which contains all the Measurement instances that match the constraints imposed by the query parameters provided.

{
    "measurements": [
        {
          "report_date": <string, ISO 8601 format>,
          "pile_yard_name": <string>,
          "pile_yard_polygon": <string, WKT MultiPolygon>,
          "total_yard_volume": <number>,
          "volume_units": <string>,
          "material_type": <string>,
          "material_density": <number>,
          "material_density_units": <string>,
          "kilotons": <number>,
          "number_of_piles": <number>,
          "number_of_piles_measured": <number>,
          "location_name": <string>,
          "location_type": <string>,
          "region_name": <string>,
          "country_name": <string>,
          "pile_yard_operator": <string>,
"image_dates": <string array, ISO 8601 format>,
"last_measured_date": <string, ISO 8601 format>,
"execution_record_ids": <[string]>,
"output_ids": <[string]>
        },
        ...
    ]
}

Example Queries

The following examples assume you have curl installed and available via your command line terminal. If you are new to curl or need help installing it on your machine, we recommend following an online guide such as https://developer.zendesk.com/documentation/api-basics/getting-started/installing-and-using-curl/ to get started.

curl --location --request POST 'https://platform.ursaspace.com/api/pas/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=<Your Ursa Space username/email>' \
--data-urlencode 'password=<Your Ursa Space password>'

If the login was successful, you should get a text response in the Response JSON Data format above. Copy the <TOKEN> text out of the response and run the final command:

export TOKEN=<TOKEN>

This will create an environment variable $TOKEN that can be used in command line queries like those shown in examples below.

Query a single report week (March 14, 2024):

curl --location --request GET 'https://platform.ursaspace.com/api/v1/smp/data?report_date_start=2024-03-14T14:00:00Z&report_date_end=2024-03-14T14:00:00Z' \
--header "Authorization: Bearer $TOKEN"
{
    "measurements": [
        {
            "report_date": "2024-03-14T14:00:00.000Z",
            "location_name": "Caofeidian",
            "location_type": "Port",
            "pile_yard_name": "Caofeidian Pile Yard 1",
            "total_yard_volume": 7793401.0,
            "region_name": "Hebei",
            "country_name": "China",
            "pile_yard_operator": "Tangshan Port Group Co., Ltd",
            "material_type": "Iron Ore",
            "material_density": 2500.0,
            "material_density_units": "kilograms per cubic meter",
            "kilotons": 19484.0,
            "image_dates": [
                "2024-03-07T12:41:08.000Z",
              "2024-03-07T12:41:38.000Z"
            ],
            "number_of_piles": 184,
            "number_of_piles_measured": 184,
            "volume_units": "cubic meters",
            "pile_yard_polygon": "MULTIPOLYGON(((118.52312865285029 38.93023996234708, 118.51929701670156 38.9336472065854, 118.53362944811629 38.94406198456536, 118.53774977941711 38.94079908790309, 118.52312865285029 38.93023996234708)),((118.50508833271944 38.919248106080445, 118.5021773325397 38.92194283581591, 118.51786991597513 38.93306778746861, 118.5218492921495 38.929469047276136, 118.50842322296988 38.919957473137615, 118.5078349673615 38.92056735579043, 118.5067579405491 38.919719575648934, 118.50631242343393 38.9201088624486, 118.50508833271944 38.919248106080445)),((118.5029642907622 38.92352187687512, 118.49891731363105 38.92680224600344, 118.50658339365921 38.93231007385277, 118.51093344837287 38.9344672731165, 118.51161091591023 38.93391565514585, 118.51515870643489 38.93639376008518, 118.51786857658436 38.93395131133203, 118.5029642907622 38.92352187687512)))",
            "last_measured_date": "2024-04-12T18:11:59.741408Z",
            "execution_record_ids": [
                "df798cc6-9e65-4120-b6d3-17990f156e87",
                "b6b29e4b-1980-4e22-b695-bc874ad2bad6",
                "8bd69421-994d-4d68-821c-91236acfef15"
            ],
            "output_ids": [
                "5a8e971e-9503-42c5-80af-272fd349ad7d",
                "e419c14e-7b8e-4bb1-aa8e-cafb9a0c0cb4",
                "49c33de8-6797-43e4-ba1e-754b8febf629",
                "9f9f3922-2954-4f02-a417-d610b0213536",
                "5dbc6c7a-ba10-4d5a-af43-42e923a863e3",
                "0f37b97a-c6ec-4b2d-8526-e775c5f84586",
              ...
            ]
        },
]
}

Query all measurements that have a report date between Tuesday, February 20, 2024 and Wednesday, March 13, 2024:

curl --location --request GET 'https://platform.ursaspace.com/api/v1/smp/data?report_date_start=2024-02-20T14:00:00Z&report_date_end=2024-03-13T14:00:00Z' \
--header "Authorization: Bearer $TOKEN"

Query measurements by pile_yard_name

curl --location --request GET 'https://platform.ursaspace.com/api/v1/smp/data?report_date_start=2024-02-20T14:00:00Z&report_date_end=2024-03-13T14:00:00Z&pile_yard_name=Mount%20Piper%20Pile%20Yard%201' \
--header "Authorization: Bearer $TOKEN"

Query measurements by material_type and region_name

curl --location --request GET 'https://platform.ursaspace.com/api/v1/smp/data?report_date_start=2024-02-20T14:00:00Z&report_date_end=2024-03-13T14:00:00Z&material_type=Iron%20Ore&region_name=Western%20Cape' \
--header "Authorization: Bearer $TOKEN"

Advanced Use Case: Accessing the Volume Measurement of Each Individual Stockpile within a Pile Yard

Up until this point we have discussed accessing data that represents the aggregated sum of all stockpile volumes within a given pile yard. But what if we need to access the volume of each individual stockpile? For this we have Ursa Space's Analytic Results Service (ARS) which is a separate API intended for advanced geospatial querying and adheres to the SpatioTemporal Asset Catalogs (STAC) specification.

As you may have already noticed by this point, each measurement returned in the GET /data endpoint has a property by the name of output_ids. Each id in this list represents an individual stockpile volume measurement that can be retrieved using the GET /items/{id} endpoint of ARS. Please see the full url below:

https://platform.ursaspace.com/api/ars/collections/stockpile_measurement_outputs_qc/items/{id}

The response is a compliant STAC Item in the following format:

{
    "properties": {
      "datetime": <string, ISO 8601 format>,
      "report_date": <string, ISO 8601 format>,
      "proj:centroid": <See the Projection Extension: https://github.com/stac-extensions/projection?tab=readme-ov-file#projection-extension-specification>
      "image_datetime": <string, ISO 8601 format>",
      "processing:software": <See the Processing Extension: https://github.com/stac-extensions/processing?tab=readme-ov-file#processing-extension-specification>,
      "ursa:analytics:qc_status": <string>,
      "ursa:analytics:measurement:uuid": <string>,
      "ursa:analytics:measurement:heightUnits": <string, should almost always be "meters">,
      "ursa:analytics:measurement:heightValue": <number>,
      "ursa:analytics:measurement:volumeUnits": <string, should almost always be "cubic meters">,
  "ursa:analytics:measurement:volumeValue": <number>
  },
"assets": {
  "image_chip": {
      "href": <string, URL (Be sure to include the Authorization header when using this url)>,
      "type": "image/tif",
          "title": "Pile Height Chip",
          "description": "Relative path to height chip for this output"
      }
  }

... For the other fields such as geometry, bbox, etc., please see the STAC Item spec defined here: https://github.com/radiantearth/stac-spec/blob/master/item-spec/item-spec.md#stac-item-specification.
}

If you would like to perform advanced geospatial queries, you can use the following the GET /search endpoint of ARS.

https://platform.ursaspace.com/api/ars/search

This endpoint conforms to the STAC Item Search specification, and supports pagination as well as the Sort, Field, and Filter extensions found on this page https://stac-api-extensions.github.io/