Introduction

The MicaSense Atlas web services APIs allow for programmatic access to MicaSense tools and services. Use these APIs to retrieve information about your account, upload and change resources, and process and retrieve data.

This documentation provides examples of two different techniques for accessing Atlas web services APIs:

  • CURL
  • Python

Base URL

All URLs referenced in the documentation have the base https://api.micasense.com/v1/.

We recommend all access to Atlas is over HTTPS.

https://api.micasense.com/v1/

Access Tokens

Access to MicaSense Atlas web services requires an access token that connects API requests to your account. The example requests in this documentation don't include an access token, it has been replaced by the text insert_token_here. You will need to supply one using the Authentication: property in your http headers. Tokens can be retrieved for your account according to the documentation below.

Content Type

All access to the MicaSense Atlas API uses JSON objects. It's necessary to set the http header Content-Type:application/json to successfully interact with the API.

Versioning

Each MicaSense Atlas API is versioned with a version string specified by the base url.

Using the newest available API is always encouraged.

These changes are considered backwards compatible and will not require the version string to be incremented:

  • Adding properties to JSON objects.
  • Changing the number of items returned in a single listing request.
  • Changing rate limiting thresholds.
  • The structure or length of identifiers generated by the API.
  • Changing error messages.

These changes are considered backwards incompatible and will require the version string to be incremented:

  • Removing properties from JSON objects.
  • Changing an API's URL structure

Dates

Most dates and times returned by the API are represented in RFC 3339 format, which can be parsed by the JavaScript Date constructor, the Python arrow library, and many other libraries and languages.

Geographic Format

All geographic objects conform to the GeoJSON specificaiton found here. Atlas uses GeoJSON Polygons extensively. The coordinate system for all Atlas inputs is WGS-84 (EPSG-4326). Output GeoTIFFs are in the UTM coordinate system appropriate to the location. Resolution of output GeoTIFFs is dependent on the ground resolution of the input images.

Tokens

Tokens are used for API access. Tokens can be created by posting a username and password to /tokens. The returned token should be used in all subsequent requests.

Note: a future extension of this API will include the usage of static tokens created from your account page within Atlas. In that case, the static tokens will be used in the same way that session tokens are used.

Manage Tokens for a Session

Property Description
expires_in expiration of the token (seconds)
token access token - save for all future access this session
POST
/tokens

Example request

curl -X POST \
   -H "Content-Type:application/json" \
   -d '{"email": "test@test.com", "password": "password"}' \
   https://api.micasense.com/v1/tokens

Example response

{"expires_in":1209600,"token":"Jedkn2s9sdfsSD20SDus92NI2s323snlkasdfjklISDFkjoSDjfaoijasdflkZDJfOISDf9ZNaWxiOXlFT1k0VnJCZGtGWUZaMHciLCJleHBpcnkiOiIxNDU5NTczODc2IiwidWlkIjoidGVzdEBtaWNhc2Vuc29sdfsd92=="}

Farms

Farms consist of a single point location and are used to organize fields. As a field belongs to a farm, it's necessary to create at least one farm before creating any fields.

List Farms

Lists all farms in your account

Property Description
id unique id of the farm - use for, e.g. creating fields in this farm
name user-friendly name of the farm
latitude WGS-84 latitude of the farm in degrees, south negative
longitude WGS-84 longitude of the farm in degrees, west negative
created_at timestamp of farm creation
updated_at timestamp of last farm update
GET
/farms

Example request

$ curl -X GET \
   -H "Content-Type:application/json" \ 
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms

Example response

{
  "farms": [
    {
      "id": 27,
      "name": "Klocko Forges",
      "latitude": 5.08667471420971,
      "longitude": 30.0573451877791,
      "info": "Et adipisci est et harum quaerat aspernatur dolores.",
      "created_at": "2016-02-19T15:30:12Z",
      "updated_at": "2016-02-19T15:30:12Z",
      "address": null
    },
    {
      "id": 28,
      "name": "Dicki Crescent",
      "latitude": 19.7398410306542,
      "longitude": -62.229115691004,
      "info": "Impedit cupiditate et. Unde eligendi non maxime et maiores.",
      "created_at": "2016-02-19T15:30:12Z",
      "updated_at": "2016-02-19T15:30:12Z",
      "address": null
    }
  ]
}

Create a Farm

Creates a new farm.

The request body is a JSON object containing the following properties.

Property Description
name (required) the name of the farm
info (optional) a description of the farm
latitude (required) the latitude of the farm in WGS84 degrees, positive North
longitude (required) the longitude of the farm in WGS84 degrees, positive east
address (optional) the address of the farm

The response is a JSON object which will contain the created information as well as the farm id and timestamps.

POST
/farms

Example request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   -d '{"name":"Furnance Creek Farms", "info":"Tourists, airplanes, and desert sands", "latitude":36.4597185, "longitude":-116.8747564, "address":"328 Greenland Blvd., Death Valley, CA 92328"}' \
   https://api.micasense.com/v1/farms

Example request body

{
  "name": "Furnance Creek Farms",
  "info": "Tourists, airplanes, and desert sands",
  "latitude": 36.4597185,
  "longitude": -116.8747564,
  "address": "328 Greenland Blvd., Death Valley, CA 92328"
}

Example response

{
  "farm": {
    "id": 715,
    "name": "Furnance Creek Farms",
    "latitude": 36.4597185,
    "longitude": -116.8747564,
    "info": "Tourists, airplanes, and desert sands",
    "created_at": "2016-03-19T06:28:13Z",
    "updated_at": "2016-03-19T06:28:13Z",
    "address": "328 Greenland Blvd., Death Valley, CA 92328"
  }
}

Retrieve a farm

Retrieve a single farm by ID.

To determine the ID of a farm by name, use the GET resource to list your farms and search the response by name or description.

GET
/farms/{farm_id}

Example request

curl -X GET \
   -H "Content-Type:application/json" \ 
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms/{farm_id}

Example response

{
  "farm": {
    "id": 715,
    "name": "Furnance Creek Farms",
    "latitude": 36.4597185,
    "longitude": -116.8747564,
    "info": "Tourists, airplanes, and desert sands",
    "created_at": "2016-03-19T06:28:13Z",
    "updated_at": "2016-03-19T06:28:13Z",
    "address": "328 Greenland Blvd., Death Valley, CA 92328"
  }
}

Update a farm

Updates the properties of a particular farm.

The request body is a JSON object containing the properties to be updated. Properties which are not included will not be modified.

Property Description
name (optional) the name of the farm
info (optional) description of the farm
latitude (optional) latitude of the farm in WGS84 degrees, positive North
longitude (optional) longitude of the farm in WGS84 degrees, positive east
address (optional) street address of the farm
PATCH
/farms/{farm_id}

Example request

curl -X PATCH \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   -d '{"info":"Tourists, sand, and desert tortoises"}' \
   https://api.micasense.com/v1/farms/{farm_id}

Example request body

{
  "info": "Tourists, sand, and desert tortoises"
}

Example response

{
  "farm": {
    "id": 715,
    "name": "Furnance Creek Farms",
    "latitude": 36.4597185,
    "longitude": -116.8747564,
    "info": "Tourists, sand, and desert tortoises",
    "created_at": "2016-03-19T06:28:13Z",
    "updated_at": "2016-03-19T06:58:01Z",
    "address": "328 Greenland Blvd., Death Valley, CA 92328"
  }
}

Delete a farm

Deletes a farm, including all fields it contains, and all data associated with those fields. Use this endpoint with extreme caution.

endpoint DELETE /farms/{farm_id}

Example request

curl -X DELETE \
   -H "Content-Type:application/json" 
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms/714

Example response

HTTP
200

Example Response Body

{}

Fields

Fields are used within Atlas to store and retrieve processed jobs. Atlas will crop the output mosiac to a buffered (slightly expanded) version of the field boundaries. Fields are organized within farms, and must exist within a farm.

Create a field

Inserts a field in a farm.

Property Description
name (required) the name of the field to create
info (optional) information about the field
bounds (required) a GeoJSON Polygon object providing the field boundary
POST
/farm/{farm_id}/fields

Example request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms/715/fields \
   -d '{ "name": "Solar Field", "bounds": { "type": "Polygon", "coordinates": [[[-116.87205702066422,36.458612090623625],[-116.87207311391829,36.45768446154288],[-116.86967521905899,36.45764131573421],[-116.86968594789505,36.45859051798032],[-116.87205702066422,36.458612090623625]]] }, "info": "Fun in the sun."}'

Example request body

{
  "name": "Solar Field",
  "bounds": {
    "type": "Polygon",
    "coordinates": [
      [
        [-116.87205702066422, 36.458612090623625],
        [-116.87207311391829, 36.45768446154288],
        [-116.86967521905899, 36.45764131573421],
        [-116.86968594789505, 36.45859051798032],
        [-116.87205702066422, 36.458612090623625]
      ]
    ]
  },
  "info": "Fun in the sun."
}

Example response

{
  "field": {
    "id": 2261,
    "name": "Solar Field",
    "bounds": {
      "type": "Polygon",
      "coordinates": [
        [
          [-116.87205702066422, 36.458612090623625],
          [-116.87207311391829, 36.45768446154288],
          [-116.86967521905899, 36.45764131573421],
          [-116.86968594789505, 36.45859051798032],
          [-116.87205702066422, 36.458612090623625]
        ]
      ]
    },
    "info": "Fun in the sun.",
    "created_at": "2016-03-20T05:30:17Z",
    "updated_at": "2016-03-20T05:30:17Z",
    "farm_id": 715,
    "area_square_meters": 22258.7534150572,
    "area_hectares": 2.22587534150572,
    "area_acres": 5.500249262627709
  }
}

List fields in a farm

List all the fields in a farm.

GET
/farms/{farm_id}/fields

Example request

url -X GET \
   -H "Content-Type:application/json" 
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms/715/fields

Example response

{
  "fields": [{
    "id": 2262,
    "name": "Airfield",
    "bounds": {
      "type": "Polygon",
      "coordinates": [
        [
          [-116.88167810440063, 36.46440197111598],
          [-116.878502368927, 36.45611825330799],
          [-116.87751531600951, 36.45646342588419],
          [-116.87983274459839, 36.46240015373378],
          [-116.87871694564818, 36.46277981272609],
          [-116.8795323371887, 36.46447099837974],
          [-116.88077688217162, 36.464022320066775],
          [-116.88099145889282, 36.46454002558205],
          [-116.88167810440063, 36.46440197111598]
        ]
      ]
    },
    "info": "No gas!",
    "created_at": "2016-03-20T05:40:45Z",
    "updated_at": "2016-03-20T05:40:45Z",
    "farm_id": 715,
    "area_square_meters": 107996.26033636,
    "area_hectares": 10.799626033636,
    "area_acres": 26.68641591041624
  }, {
    "id": 2260,
    "name": "Solar Field",
    "bounds": {
      "type": "Polygon",
      "coordinates": [
        [
          [-116.87205702066422, 36.458612090623625],
          [-116.87207311391829, 36.45768446154288],
          [-116.86967521905899, 36.45764131573421],
          [-116.86968594789505, 36.45859051798032],
          [-116.87205702066422, 36.458612090623625]
        ]
      ]
    },
    "info": "Fun in the sun.",
    "created_at": "2016-03-20T05:25:10Z",
    "updated_at": "2016-03-20T05:25:10Z",
    "farm_id": 715,
    "area_square_meters": 22258.7534150572,
    "area_hectares": 2.22587534150572,
    "area_acres": 5.500249262627709
  }]
}

Retrieve a field

Retrieves a field by ID.

GET
/fields/{field_id}

Example request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/fields/2261

Example response

{
  "field": {
    "id": 2261,
    "name": "Solar Field",
    "bounds": {
      "type": "Polygon",
      "coordinates": [
        [
          [-116.87205702066422, 36.458612090623625],
          [-116.87207311391829, 36.45768446154288],
          [-116.86967521905899, 36.45764131573421],
          [-116.86968594789505, 36.45859051798032],
          [-116.87205702066422, 36.458612090623625]
        ]
      ]
    },
    "info": "Fun in the sun.",
    "created_at": "2016-03-20T05:30:17Z",
    "updated_at": "2016-03-20T05:30:17Z",
    "farm_id": 715,
    "area_square_meters": 22258.7534150572,
    "area_hectares": 2.22587534150572,
    "area_acres": 5.500249262627709
  }
}

Delete a field

Removes a field, including all processed data outputs with that field. Use with caution.

DELETE
/fields/{field_id}

Example request

curl -X DELETE \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/fields/2261

Example response

HTTP
200

ImageSets

An ImageSet is a container for a group of uploaded files which, at minimum, contain data covering one field, but may contain data covering many fields simultaneously. An ImageSet can include data from one or more flights gathered over one or more days.

The main limitation with organizing data in an ImageSet is that data captured for the same field at two different times (or two different altitudes), which is mean to be processed into two different output maps, should be added to two different ImageSets. In other words, only one output map can be generated for each field covered by a single ImageSet.

For example, 2 flights were flown on Thursday over Field A, each covering half of the field. A third flight was flown on Thursday over Field B, covering the whole field. Data from all 3 flights can be combined in the same ImageSet. The API user will have the opportunity to create two output maps, one each for Field A and Field B.

In another case, 2 flights were flown on Monday over Field C. One flight was flown at 9AM, covering the whole field. The second was flown at 3PM, also covering the whole field. The intent of the flights was to measure the difference in crop reflectance at two separate times of day. In this case, the data from each flight should be uploaded to a separate ImageSet. A processing result can then be generated for each flight separately.

In a third example, a field is flown on the same day at three different altitudes, 50, 75, and 100 meters above ground, to test resolution requrements for identification of a specific issue. Since three output maps of the same field are desired, the data needs to be uploaded to three separate ImageSets.

Create ImageSet

Create an ImageSet which will serve as a container for uploaded files.

Propery Description
title (requred) human friendly imagest title
description (optional) human friendly imageset description. plain text
expected_file_count (optional) expected number of files to be uploaded to the ImageSet
POST
/image_sets

Example Request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets \
   -d '{ "image_set": { "title": "Test Image Set", "description": "A description of the image set", "expected_file_count": 1234 } }'

Example Request Body

{
  "image_set": {
    "title": "Test Image Set",
    "description": "A description of the image set",
    "expected_file_count": 1234
  }
}

Example Response

{
  "image_set": {
    "id": 1060,
    "user_id": 1,
    "pending": true,
    "title": "Test Image Set",
    "description": "A description of the image set",
    "area": null,
    "created_at": "2016-03-20T22:48:53Z",
    "total_flights": 0,
    "captured_at": null,
    "total_captures": 0,
    "total_files": 0,
    "processing_summary": {
      "unscheduled_mosaic_request_count": 0,
      "pending_mosaic_request_count": 0,
      "rejected_mosaic_request_count": 0,
      "complete_mosaic_request_count": 0,
      "status": "uploading"
    },
    "expected_file_count": 1234,
    "percent_upload_complete": 0.0
  }
}

Retrieve ImageSet

Get a single ImageSet by ID.

GET
/image_set/{imageset_id}

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1060

Example Response

{
  "image_set": {
    "id": 1060,
    "user_id": 1,
    "pending": true,
    "title": "Test Image Set",
    "description": "A description of the image set",
    "area": null,
    "created_at": "2016-03-20T22:48:53Z",
    "total_flights": 0,
    "captured_at": null,
    "total_captures": 0,
    "total_files": 0,
    "processing_summary": {
      "unscheduled_mosaic_request_count": 0,
      "pending_mosaic_request_count": 0,
      "rejected_mosaic_request_count": 0,
      "complete_mosaic_request_count": 0,
      "status": "uploading"
    },
    "expected_file_count": 1234,
    "percent_upload_complete": 0.0
  }
}

Update ImageSet

Update specific fields in an ImageSet, such as the name.

This endpoint is also used to mark an ImageSet complete, telling Atlas that all necessary StoredFiles have been added to the ImageSet, uploaded to S3, and marked as complete.

PUT
/image_set/{imageset_id}

Example Request

curl -X PUT \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1060 \
   -d '{ "image_set": { "title": "Test Image Set Changed"} }'

Example Response

{
  "image_set": {
    "id": 1060,
    "user_id": 1,
    "pending": true,
    "title": "Test Image Set Changed",
    "description": "A description of the image set",
    "area": null,
    "transform": null,
    "created_at": "2016-03-20T22:48:53Z",
    "total_flights": 0,
    "captured_at": null,
    "total_captures": 0,
    "total_files": 0,
    "processing_summary": {
      "unscheduled_mosaic_request_count": 0,
      "pending_mosaic_request_count": 0,
      "rejected_mosaic_request_count": 0,
      "complete_mosaic_request_count": 0,
      "status": "uploading"
    },
    "expected_file_count": 1234,
    "percent_upload_complete": 0.0
  }
}

Delete ImageSet

Update specific fields in an ImageSet, such as the name.

DELETE
/image_sets/{imageset_id}

Example Request

curl -X DELETE \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1060

Example Response

HTTP
200

List ImageSets

List all imagesets associated with the account.

Note: listing all ImageSets can be a performance hit. Use the limit parameter to only request the past few ImageSets.

GET
/imagesets?limit={limit}

Example Request

curl -X DELETE \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets?limit=10

Example Response

{
  "image_sets": [{
    "id": 1052,
    "user_id": 1,
    "pending": true,
    "title": "2016-03-04 13:22:24",
    "description": "",
    "area": null,
    "transform": null,
    "created_at": "2016-03-04T21:22:31Z",
    "total_flights": 1,
    "captured_at": "2015-08-19T14:44:47Z",
    "total_captures": 4,
    "total_files": 7,
    "processing_summary": {
      "unscheduled_mosaic_request_count": 0,
      "pending_mosaic_request_count": 0,
      "rejected_mosaic_request_count": 0,
      "complete_mosaic_request_count": 0,
      "status": "uploading"
    },
    "expected_file_count": 7,
    "percent_upload_complete": 100.0,
    "registration_status": "None"
  }]
}

StoredFiles

Stored files are used to upload files to the Atlas API, incuding both imagery files and camera log files. StoredFiles always belong to an ImageSet.

The following process can be used to create and uploading a stored file:

  1. Compute the SHA-1 hash of the file to be uploaded
  2. Create the StoredFile by POSTing the hash and original filename to /imageset/{imageset_id}/files
  3. Use the upload_url in the returned object to upload the data directly to S3
  4. When the upload of the file to S3 is complete, let Atlas know by POSTing to the provided id at /files/{file_id}/complete.

In this way you can create a StoredFile for each image captured. You can also use StoredFiles to upload extra files, such as RedEdge diagnostic files (paramlog.dat and diag.dat), direclty to an ImageSet. These files can be useful if issues arise with a camera or imageset, so we recommend always including these files in your uploads.

The SHA-1 hash of a file can be computed from the linux command line using the command:

sha1sum filename.tif

The SHA-1 hash can be computed programmatically in python using the sha package or in JavaScript using the crypto node package.

Create StoredFile

StoredFiles are required to be assoicated with an ImageSet.

Parameter Description
file_hash 40 character SHA-1 hash of the file to be uploaded
original_filename original filename of the file as written by the camera
POST
/image_sets/{imageset_id}/files/

Example Request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1060/files \
   -d '{ "file": { "file_hash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", "original_filename": "original.jpg" } }'

Example Response

{
  "file": {
    "id": 1232,
    "file_hash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
    "owner_id": 166,
    "owner_type": "ImageSet",
    "original_filename": "original.jpg",
    "complete": false,
    "upload_url": "https://brent-dev-bucket.s3.amazonaws.com/upload/1232?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327881&Signature=mwOwsuBJuCc9UP9P5gWALQp74B8%3D",
    "download_url": "https://brent-dev-bucket.s3.amazonaws.com/upload/1232?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327881&Signature=D1FheD5y55Sk1XY269wMAOex0z8%3D"
  }
}

Retrieve a StoredFile

GET
/files/{file_id}

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/files/1240

Example Response

{
  "file": {
    "id": 1240,
    "file_hash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
    "owner_id": 168,
    "owner_type": "ImageSet",
    "original_filename": "IMG_0000_1.tif",
    "complete": false,
    "upload_url": "https://s3-bucket.s3.amazonaws.com/upload/1240?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=%2FuctETqtVLLUEoMvhjs%2BU%2BI9CxQ%3D",
    "download_url": "https://s3-bucket.s3.amazonaws.com/upload/1240?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=DDgVwxH1XyPJvqfMc6hq1A2g9eU%3D"
  }
}

Complete a StoredFile

Inform Atlas that a file upload has been completed.

POST
/files/{file_id}/complete

Example Request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/files/1240/complete

Example Response

{
  "file": {
    "id": 1240,
    "file_hash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
    "owner_id": 168,
    "owner_type": "ImageSet",
    "original_filename": "IMG_0000_1.tif",
    "complete": true,
    "upload_url": "https://s3-bucket.s3.amazonaws.com/upload/1240?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=%2FuctETqtVLLUEoMvhjs%2BU%2BI9CxQ%3D",
    "download_url": "https://s3-bucket.s3.amazonaws.com/upload/1240?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=DDgVwxH1XyPJvqfMc6hq1A2g9eU%3D"
  }
}

Delete a StoredFile

Delete a StoredFile from Atlas. The file in S3 will also be immediately deleted.

DELETE
/files/{file_id}

Example Request

curl -X DELETE \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/files/1240

Example Response

HTTP
200

List StoredFiles

GET
/image_sets/{imageset_id}/files

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1060/files

Example Response

{
  "files": [
    {
      "id": 1245,
      "file_hash": "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
      "owner_id": 170,
      "owner_type": "ImageSet",
      "original_filename": "IMG_0000_1.tif",
      "complete": true,
      "upload_url": "https://s3-bucket.s3.amazonaws.com/upload/1245?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=HPA2LOSZ2GcM1S1xxq8dwE8I1Ms%3D",
      "download_url": "https://s3-bucket.s3.amazonaws.com/upload/1245?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=388VhJj0d1sHrQpwrqtFK0G7658%3D"
    },
    {
      "id": 1244,
      "file_hash": "fxUByC4mwLPp_4xqDPesjQ",
      "owner_id": 170,
      "owner_type": "ImageSet",
      "original_filename": "IMG_0000_1.tif",
      "complete": true,
      "upload_url": "https://s3-bucket.s3.amazonaws.com/upload/1244?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=guvzoq1tyg0vXxWz84vYyfHQqvA%3D",
      "download_url": "https://s3-bucket.s3.amazonaws.com/upload/1244?AWSAccessKeyId=AKIAJIX4I5WPWEUOEGSA&Expires=1456327882&Signature=k16IJyzWmph3UWPXwz3djxdk0mQ%3D"
    }
  ]
}

CoveredFields

CoveredFields are used to determine which field(s) an ImageSet's captures cover. If automatic processing is enabled in the Atlas account, fields which are covered by more than 80% are processed automatically. When using the API, it may be useful to disable this option and programmatically process fields at the time of upload, but this is not required.

List Covered Fields

The list of CoveredFields will be an array of objects, each of which includes a field, mosaic_request, and mosaic.

Property Description
covered_fields list of objects each with a property as below
field field id of the covered field
mosaic_request mosaic_request object
mosaic mosaic object
area_acres the area of the covered covered
average_alt_agl the average altitude above ground of the captured images
coverage_percent the percentage of the field that is covered by the captured images in this ImageSet

A further description of MosaicRequest and Mosiac objects and how to use them is defined below.

In the example response, we find 3 covered fields, each in different stages of processing.

If both the mosaic_request object and mosiac object are null, processing has not been requested for this covered field. Processing can begin by creating a new MosaicRequest using the ImageSet and Field ids as described below.

If the mosaic_request object is not null but the mosaic object is null, processing has been requested but an output for this covered field has not yet been generated.

If the mosaic object id is not null, an output has been generated for this field. Request the mosaic using it's id to retrieve the mosaic information.

GET
/image_sets/{imageset_id}/covered_fields

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/1059/covered_fields

Example Response

{
  "covered_fields": [
    {
      "field": { "id": 7654 },
      "mosaic_request": null,
      "mosaic": null,
      "area_acres": 334.5,
      "average_alt_agl": 123.2,
      "coverage_percent": 82.32
    },
    {
      "field": { "id": 654 },
      "mosaic_request": { "id": "mosaic_request_uuid" },
      "mosaic": null
      "area_acres": 1.22,
      "average_alt_agl": 98.2,
      "coverage_percent": 72.1
    },
    {
      "field": { "id": 321},
      "mosaic_request": { "id": "mosaic_request_uuid" },
      "mosaic": { "id": "mosaic_uuid" }
      "area_acres": 1234.5,
      "average_alt_agl": 234.6,
      "coverage_percent": 99.8
    }
  ]
}

MosaicRequests

MosiacRequests represent a request to create a mosaic from a specific image set for a specific field.

Create MosaicRequest

Create a MosaicRequest to request a processing output for a specific Field covered by an ImageSet. Use /covered_fields to determine if a MosaicRequest covers a specific field.

Creating the MosaicRequest will kick off the processing required to create the expected mosaic. The mosaic status field will be updated when the request is fulfilled and the resulting Mosaic is ready.

Property Description
image_set_id (required) the id of the imageset to process images from
field_id (required) the id of the field for which to create a map. Outputs will be cropped to this field's boundaries.
POST
/mosaic_requests

Example Request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests
   -d { "mosaic_request": { "image_set_id": 117, "field_id": 66 }
}

Example Response

{
  "mosaic_request": {
      "id": "0b334aa6-8227-45d1-9375-e755e65c1e0b",
      "created_at": "2015-08-13T19:53:02Z",
      "completed_at": "2015-08-13T20:49:37Z",
      "field_id": 66,
      "image_set_id": 117,
      "mosaic_id": "8d58b27f-0e03-4667-b455-d9663e3c8ae4",
      "cost_estimate": null,
      "cost": 0,
      "status": "complete",
      "average_altitude_meters": 174.670725806452,
      "average_altitude_agl_meters": 80.6223387096774194,
      "capture_start_time": "2015-05-28T19:24:09Z",
      "capture_end_time": "2015-05-28T19:26:15Z",
      "process_start_time": null,
      "process_end_time": null,
      "captures_area_square_meters": 8383.57965718221,
      "percent_coverage": 100.000,
      "message": null,
      "area_acres": 2.07162
    }
}

Billing Errors

An active processing plan with proper billing information is required to process data with Atlas. Log in to the Atlas web interface to update your plan or billing information. In some cases, charges to your account may fail, preventing creation of a MosaicRequest. In these cases, a HTTP 409 will be returned.

Example Request

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests
   -d { "mosaic_request": { "image_set_id": 117, "field_id": 66 }
}

Billing Error Example Response

HTTP 409
{
  "message": "Billing issue for name@email.com"
}

Retrieve MosaicRequest

Get a MosaicRequest

GET
/mosaic_requests/{mosaic_request_id}

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests/{mosaic_request_id}

Example Response

{
  "mosaic_request": {
      "id": "0b334aa6-8227-45d1-9375-e755e65c1e0b",
      "created_at": "2015-08-13T19:53:02Z",
      "completed_at": "2015-08-13T20:49:37Z",
      "field_id": 401,
      "image_set_id": 260,
      "mosaic_id": "8d58b27f-0e03-4667-b455-d9663e3c8ae4",
      "cost_estimate": null,
      "cost": 0,
      "status": "complete",
      "average_altitude_meters": 174.670725806452,
      "average_altitude_agl_meters": 80.6223387096774194,
      "capture_start_time": "2015-05-28T19:24:09Z",
      "capture_end_time": "2015-05-28T19:26:15Z",
      "process_start_time": null,
      "process_end_time": null,
      "captures_area_square_meters": 8383.57965718221,
      "percent_coverage": 100.000,
      "message": "Processing message",
      "area_acres": 2.0716244511806465
    }
}

Delete MosaicRequest

Delete a mosaic request. This will also delete any processed outputs from it. Note: a mosaic request in process may still be charged to your account.

DELETE
/mosaics/{mosaic_id}

Example Request

curl -X DELETE \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests/{mosaic_request_id}

Example Response

HTTP
200

Mosaics

A finished output product with geotiff and rendered layers. Mosaics are created by Atlas in response to MosaicRequests, therefore they can only be retrieved.

Retrieve Mosaic

GET
/mosaics/{mosaic_id}

Example Request

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaics/{mosaic_id}

Example Response

{
  "mosaic": {
    "id": "8d58b27f-0e03-4667-b455-d9663e3c8ae4",
    "field_id": 401,
    "message": "Processing Message",
    "extent": {
      "type": "Polygon",
      "coordinates": [[1,2],[3,4],[5,6]]
    },
    "artifacts": {
      "geotiff": {
        "exists": true,
        "download_url": "https://path.to.download/file.tif"
      },
      "dsm": {
        "exists": true,
        "download_url": "https://path.to.download/file.tif"
      }
    },
    "created_at": "2015-08-13T20:46:28Z",
    "updated_at": "2015-08-13T20:46:28Z",
    "captured_at": "2015-07-12T10:53:23Z"
  }
}

Example Use Case

The MicaSense Atlas API transforms raw multispectral images into georeferenced orthomosaics and web-accessable tilesets.

The Atlas workflow begins by creating farms and fields within Atlas. Farms have a name and optional descripion as well as a point location. Farms group together fields for easier management and navigation. Fields are defined by a name, description, and polyon defining an outline.

Before we can start, we we need to retrive a token or use our account's API access key.

Get Access Token

curl -X POST \
   -H "Content-Type:application/json" \
   -d '{"email": "test@test.com", "password": "password"}' \
   https://api.micasense.com/v1/tokens

Farm and Field Setup

First we set up our account by defining Farms and Fields.

  1. Define a Farm

  2. Define each Field belonging to the Farm

Create Farm

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   -d '{"name":"Furnance Creek Farms", "info":"Tourists, airplanes, and desert sands", "latitude":36.4597185, "longitude":-116.8747564, "address":"328 Greenland Blvd., Death Valley, CA 92328"}' \
   https://api.micasense.com/v1/farms

Create Field

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/farms/{farm_id}/fields \
   -d '{ "name": "Solar Field", "bounds": { "type": "Polygon", "coordinates": [[[-116.87205702066422,36.458612090623625],[-116.87207311391829,36.45768446154288],[-116.86967521905899,36.45764131573421],[-116.86968594789505,36.45859051798032],[-116.87205702066422,36.458612090623625]]] }, "info": "Fun in the sun."}'

ImageSet Creation

Next, we create ImageSets for each set of data that we want to upload:

  1. Create an ImageSet
  2. Create StoredFiles belonging to the ImageSet for each file to be uploaded
  3. Mark each StoredFile complete after uploading it to the provided S3 URL
  4. After uploading all files, mark the ImageSet status to complete

Create ImageSet

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets \
   -d '{ "image_set": { "title": "Test Image Set", "description": "A description of the image set", "expected_file_count": 1234 } }'

Create Stored File in ImageSet

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/{image_set_id}/files \
   -d '{ "file": { "file_hash": "abcd1234", "original_filename": "original.jpg" } }'

Upload file to provided S3 URL, then Mark as Complete

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/files/{stored_file_id}/complete

Mark ImageSet as Complete

curl -X PUT \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_set/{image_set_id}
   -d {"pending": false}

MosaicRequest Creation

  1. Request the CoveredFields for the ImageSet,
  2. Use the appropriate CoveredField id and ImageSet id to create a MosaicRequest
  3. Poll the status of the MosaicRequest using it's ID
  4. When the MosaicRequest is complete, get the associated Mosaic object
  5. Using the paths in the Mosaic object, download the raw GeoTiff and DSM from S3.

Request CoveredFields

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/image_sets/{image_set_id}/covered_fields

Create a MosaicRequest

curl -X POST \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests
   -d { "mosaic_request": { "image_set_id": 117, "field_id": 66 }
}

Poll Status of MosiacRequest

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaic_requests/{mosaic_request_id}

Get Mosaic Object

curl -X GET \
   -H "Content-Type:application/json" \
   -H "Authorization:insert_token_here" \
   https://api.micasense.com/v1/mosaics/{mosaic_id}

Download Results

wget https://path.to.mosaic/file.tif

GeoTiff Uploads

Geotiff uploads are useful if you want to process your own data (e.g. with Pix4D or Agisoft), but still utilize the storage, management, and analysis capabilites of Atlas.

The Atlas Uploads API transforms reflectance compensated geotiffs into tilesets that can be used with online maps and geographic applications. Uplaods should be in the UTM coordinate system.

The upload workflow begins with a file and ends with a mosaic available in the Atlas online viewer, or if you have invalid data, an error.

  1. Retrieve S3 credentials to stage the file
  2. Use an S3 client, like the AWS SDK, to upload a file to S3 using those credentials
  3. Create a mosaic using the staged file's URL
  4. Retrieve the upload's status as it is processed into a tileset
  5. Once the upload is complete, use the tileset ID like you'd use any other tileset

Retrieve S3 credentials

MicaSense provides an Amazon S3 bucket to stage your file while your upload is processed. Uploads must be staged in this bucket before being uploaded to your Mapbox account. You can retrieve temporary credentials from this endpoint.

The response body is a JSON object containing the following properties.

Property Description
accessKeyId AWS Access Key ID
bucket S3 bucket name
key unique key for data to be staged
secretAccessKey AWS Secret Access Key
sessionToken temporary security token
url destination URL of the file

Use these credentials to store your data in the provided bucket with the provided key using the AWS CLI or AWS SDK? of your choice. The bucket is located in AWS region us-west-1.

GET
/uploads/credentials

Example request

curl https://api.micasense.com/v1/uploads/credentials

Example response

{
  "accessKeyId": "{accessKeyId}",
  "bucket": "somebucket",
  "key": "hij456",
  "secretAccessKey": "{secretAccessKey}",
  "sessionToken": "{sessionToken}",
  "url": "{url}"
}

Example AWS CLI usage

aws s3 cp file {url} 

Create an upload

Once you've used the temporary S3 credentials to transfer your file to Mapbox's staging bucket, you can trigger the generation of a tileset given the file's URL and a destination tileset ID.

The request body is a JSON object containing the following properties.

Property Description
tileset the map ID to create or replace in the format username.nameoftileset
url HTTPS URL of the S3 object provided in the credential request
name (optional) name for the tileset

Reuse of a tileset value will replace existing data: use a random value to make sure that a new tileset is created, or check existing tilesets first.

The response body is a JSON object containing the following properties.

Property Description
complete whether the upload is complete (true) or not (false)
tileset The id of the tileset (map) that will be created or replace if upload` is successful
error if null, the upload is in progress or successfully completed. Otherwise, a brief explanation of the error
id the unique identifier for the upload
name the name of the upload
modified time when the upload resource was last modified
created time when the upload resource was created
owner the unique identifier for the owner's account
progress the progress of the upload expressed as a float between 0 and 1
POST
/uploads

Example request

curl -X POST https://api.micasense.com/v1/uploads

Example request body

{
  "tileset": "{username}.mytileset",
  "url": "http://somebucket.s3.amazonaws.com/markers.json",
  "name": "example-markers"
}

Example response

{
  "complete": false,
  "tileset": "example.markers",
  "error": null,
  "id": "hij456",
  "name": "example-markers",
  "modified": "{timestamp}",
  "created": "{timestamp}",
  "owner": "{username}",
  "progress": 0
}

Retrieve upload status

Upload processing is fast but not immediate. Once an upload is created, you can track its status. Uploads have a progress property that will start at 0 and end at 1 when an upload is complete. If there's an error processing an upload, the error property will include an error message.

GET
/uploads/{upload_id}

Example Request

curl https://api.micasense.com/v1/uploads/{upload_id}

Example Response

{
  "complete": true,
  "tileset": "example.markers",
  "error": null,
  "id": "hij456",
  "name": "example-markers",
  "modified": "{timestamp}",
  "created": "{timestamp}",
  "owner": "{username}",
  "progress": 1
}

Retrieve recent upload statuses

You can retrieve multiple upload statuses at the same time, sorted by the most recently created. This request returns the same information as individual upload status, but for all recent uploads. The list is limited to 1MB of JSON.

This endpoint supports pagination so that you can list many uploads. Up to 100 items can be requested at a time using the limit parameter. It also supports another parameter, reverse:

Parameter Description
reverse List uploads in chronological order, rather than reverse chronological order.
GET
/uploads

Example Request

curl https://api.micasense.com/v1/uploads

Example Response

[{
  "complete": true,
  "tileset": "example.mbtiles",
  "error": null,
  "id": "abc123",
  "name": null,
  "modified": "2014-11-21T19:41:10.000Z",
  "created": "2014-11-21T19:41:10.000Z",
  "owner": "example",
  "progress": 1
}, {
  "complete": false,
  "tileset": "example.foo",
  "error": null,
  "id": "xyz789",
  "name": "foo",
  "modified": "2014-11-21T19:41:10.000Z",
  "created": "2014-11-21T19:41:10.000Z",
  "owner": "example",
  "progress": 0
}]

Remove an upload

Remove a completed upload status from the upload listing.

An upload cannot be removed until it is completed.

DELETE
/uploads/{upload_id}

Example Request

$ curl -X DELETE https://api.micasense.com/v1/uploads/{upload_id}

Example Response

HTTP
200
Show examples in:
MicaSense Atlas API Documentation