API Examples
These examples align with the FHI Swagger contract: Swagger UI.
Raw OpenAPI spec: OpenAPI JSON
Submit an Enrollment
Enrollment requests are multipart/form-data: a request part with JSON enrollment metadata and a geojson part
with field boundaries.
- cURL
- Python
- JavaScript
const axios = require('axios')
const fs = require('fs')
const FormData = require('form-data')
const FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
const endpoint = `${FHI_INSTANCE_URL}/v1/enrollments`
const form = new FormData()
form.append('request', fs.createReadStream('enrollment-request.json'), { contentType: 'application/json' })
form.append('geojson', fs.createReadStream('fields.geojson'), { contentType: 'application/geo+json' })
axios.post(endpoint, form, {
headers: {
'Api-Key': 'YOUR_API_KEY',
...form.getHeaders(),
},
})
.then(res => console.log(res.data))
.catch(console.error)
import requests
FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
endpoint = f'{FHI_INSTANCE_URL}/v1/enrollments'
headers = { 'Api-Key': 'YOUR_API_KEY' }
files = {
'request': ('enrollment-request.json', open('enrollment-request.json', 'rb'), 'application/json'),
'geojson': ('fields.geojson', open('fields.geojson', 'rb'), 'application/geo+json'),
}
response = requests.post(endpoint, headers=headers, files=files)
print(response.json())
curl --location --request POST '{FHI_INSTANCE_URL}/v1/enrollments' \
--header 'Api-Key: YOUR_API_KEY' \
--form 'request=@"enrollment-request.json";type=application/json' \
--form 'geojson=@"fields.geojson";type=application/geo+json'
enrollment-request.json
{
"image_source": "planet",
"start_date": "2025-01-01",
"end_date": "2025-12-31",
"description": "meaningful customer description",
"layers": [
{ "layer": "ndvi" },
{ "layer": "vegetation" },
{ "layer": "scouting" },
{ "layer": "true-color" }
]
}
fields.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": { "field_id": "field-us-1" },
"geometry": {
"type": "Polygon",
"coordinates": [
[
[ -93.6, 41.6 ],
[ -93.6, 41.61 ],
[ -93.59, 41.61 ],
[ -93.59, 41.6 ],
[ -93.6, 41.6 ]
]
]
}
}
]
}
Submit Enrollment Response Sample
{
"enrollment_id": "id-1",
"message": "Enrollment received OK.",
"request_metadata": {
"image_source": "planet",
"start_date": "2025-01-01",
"end_date": "2025-12-31",
"layers": [
{ "layer": "ndvi" },
{ "layer": "vegetation" },
{ "layer": "scouting" },
{ "layer": "true-color" }
]
},
"status": "received",
"total_fields": 1,
"processed_fields": 0,
"failed_fields": 0,
"created_date_time": "2026-01-22T21:22:07.240796Z"
}
Submission is asynchronous — you can continue without waiting for processing to complete. Use the enrollment status endpoint to check progress.
Get Enrollment Status
- cURL
- Python
- JavaScript
const axios = require('axios')
const FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
const ENROLLMENT_ID = 'YOUR_ENROLLMENT_ID'
const endpoint = `${FHI_INSTANCE_URL}/v1/enrollments/${ENROLLMENT_ID}`
axios.get(endpoint, { headers: { 'Api-Key': 'YOUR_API_KEY' } })
.then(res => console.log(res.data))
.catch(console.error)
import requests
FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
ENROLLMENT_ID = 'YOUR_ENROLLMENT_ID'
endpoint = f'{FHI_INSTANCE_URL}/v1/enrollments/{ENROLLMENT_ID}'
headers = { 'Api-Key': 'YOUR_API_KEY' }
response = requests.get(endpoint, headers=headers)
print(response.json())
curl --location --request GET '{FHI_INSTANCE_URL}/v1/enrollments/{ENROLLMENT_ID}' \
--header 'Api-Key: YOUR_API_KEY'
Get Enrollment Status Response Sample
{
"enrollment_id": "id-1",
"message": "Enrollment received OK.",
"request_metadata": { "image_source": "planet", "start_date": "2025-01-01", "end_date": "2025-12-31" },
"status": "completed",
"total_fields": 1,
"processed_fields": 1,
"failed_fields": 0,
"created_date_time": "2026-01-22T21:22:07.240796Z",
"completed_date_time": "2026-01-22T21:40:00.000000Z",
"errors": null
}
Possible status values: received, in_progress, completed, failed.
List Enrollments
- cURL
- Python
- JavaScript
const axios = require('axios')
const FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
const endpoint = `${FHI_INSTANCE_URL}/v1/enrollments?status=completed&limit=50`
axios.get(endpoint, { headers: { 'Api-Key': 'YOUR_API_KEY' } })
.then(res => console.log(res.data))
.catch(console.error)
import requests
FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
endpoint = f'{FHI_INSTANCE_URL}/v1/enrollments'
headers = { 'Api-Key': 'YOUR_API_KEY' }
params = { 'status': 'completed', 'limit': 50 }
response = requests.get(endpoint, headers=headers, params=params)
print(response.json())
curl --location --request GET '{FHI_INSTANCE_URL}/v1/enrollments?status=completed&limit=50' \
--header 'Api-Key: YOUR_API_KEY'
To fetch subsequent pages, pass the cursor value from the previous response back as the cursor query parameter.
Access Generated Imagery via SAS Token
FHI writes generated imagery directly to a storage container. Request a SAS token, then use any storage-compatible SDK, CLI, or browser to list and download files.
- cURL
- Python
- JavaScript
const axios = require('axios')
const FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
const endpoint = `${FHI_INSTANCE_URL}/v1/auth/sas-token`
axios.get(endpoint, { headers: { 'Api-Key': 'YOUR_API_KEY' } })
.then(res => console.log(res.data))
.catch(console.error)
import requests
FHI_INSTANCE_URL = 'YOUR_FHI_INSTANCE_URL'
endpoint = f'{FHI_INSTANCE_URL}/v1/auth/sas-token'
headers = { 'Api-Key': 'YOUR_API_KEY' }
response = requests.get(endpoint, headers=headers)
print(response.json())
curl --location --request GET '{FHI_INSTANCE_URL}/v1/auth/sas-token' \
--header 'Api-Key: YOUR_API_KEY'
Get SAS Token Response Sample
{
"account_name": "yourstorageaccount",
"file_system": "yourcontainer",
"sas_token": "sv=2025-01-01&ss=b&srt=co&sp=r&se=...&sig=...",
"path": "{customer}/fhi/planet/"
}
Use the returned account_name, file_system, and sas_token to browse the deterministic output path:
{customer}/fhi/planet/{field_id}/{date}/{image_type}.tiff
Example: bayer/fhi/planet/FIELD_001/2025-02-15/ndvi.tiff