Python Examples
A pre-requisite for exchanging requests with the various Orders API endpoints is to have a valid authentication token and contract_id, see Authentication API. In the examples below, the headers in the requests have placeholders for token and contract_id.
import requests
import json
# 0. Complete the following section with your contract_id and access token
#contract_id = ""
#ACCESS_TOKEN = ""
ALEPH_API_URL = "https://api.satellogic.com"
Get all orders in my contract
ORDERS_URI = "/v2/orders/"
response = requests.get(
f"{ALEPH_API_URL}{ORDERS_URI}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
orders = response.json()
print(json.dumps(orders, indent=4))
Sample output:
{
"type": "FeatureCollection",
"count": 322,
"next": "/v2/orders?offset=25&limit=25",
"previous": null,
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-68.285557111,
-34.620848878,
664.040039062
]
},
"properties": {
"order_id": "000383",
"contract_id": "cont.12345678-6863-4375-a89e-c832b32a5350",
"contract_name": "my_contract",
"project_id": "project.1234abcd-55ee-460b-8d37-70a3145499ae",
"project_name": "Python examples",
"sku": "TSKRSH-M.NN.NN",
"product_name": "Rush Tasking",
...
}
}
]
}
Get order details
ORDER_ID = "000077"
response = requests.get(
f"{ALEPH_API_URL}{ORDERS_URI}{ORDER_ID}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
order_details = response.json()
print(json.dumps(order_details, indent=4))
Sample output:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-57.575179022,
-37.935767493,
17.003490448
]
},
"properties": {
"order_id": "000077",
"contract_id": "cont.12345678-6863-4375-a89e-c832b32a5350",
"contract_name": "my_contract",
"project_id": "project.1234abcd-73ed-4e21-8478-3658c2def1a6",
"project_name": "Python examples",
"sku": "TSKRSH-M.NN.NN",
"product_name": "Rush Tasking",
"order_name": "Mar del Plata Airport",
"parameters": {
"start": "2025-10-30T19:01:00Z",
"end": "2025-11-21T23:59:00Z",
"revisit_period": "P1D",
"min_ona": null,
...
"timestamp": "2025-11-05T22:43:46.813061Z"
}
}
}
Get all captures for my tasking order
CAPTURES_URI = "/captures/"
response = requests.get(
f"{ALEPH_API_URL}{ORDERS_URI}{ORDER_ID}{CAPTURES_URI}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
capture_details = response.json()
print(json.dumps(capture_details, indent=4))
Get capture attempts, with a given status within a period of time
CAPTURES_URI = "/v2/captures/"
params = {
'status': 'failed',
'limit': 10,
'start__gt': '2025-11-09', # collection time greater than
'end__lt': '2025-11-11' # collection time lower than
}
response = requests.get(
f"{ALEPH_API_URL}{CAPTURES_URI}",
headers={
'authorizationToken': f'Bearer {token}',
'X-Satellogic-Contract-Id': "cont.16937a59-6863-4375-a89e-c832b32a5350"
},
params=params
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
capture_details = response.json()
print(json.dumps(capture_details, indent=4))
Sample output:
{
"type": "FeatureCollection",
"count": 1,
"next": null,
"previous": null,
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-57.549446859,
-37.841249789,
0.017003699
],
...
[
-57.600976835,
-38.030277471,
0.017003803
]
]
},
"properties": {
"capture_id": "14f3c25b-9c5b-4c00-9536-bd145a803493",
"satellite": "newsat40",
"status": "failed",
"start": "2025-11-09T17:35:32.971264",
"end": "2025-11-09T17:37:19.006536",
"order": "000077",
"created_at": "2025-11-09T17:12:51.046436",
"updated_at": "2025-11-10T09:42:51.612776",
"metadata": {
"min_absolute_off_nadir": 23.898832826852953,
"max_absolute_off_nadir": 24.70535646230271,
"min_sun_elevation": 55.8839266259931,
"max_sun_elevation": 55.95499051967367,
"priority": 75
},
"latest_event": {
"id": "15e6678e-f170-4d69-ac7a-eb7a499d15af",
"type": "CaptureCollectionFailed",
"details": {
"reason": "Collection attempt failed."
},
"message": "CaptureCollectionFailed event occurred for order 000077",
"timestamp": "2025-11-10T09:42:49.663410Z"
}
}
}
]
}
Get all deliverables for my order ID
DELIVERABLES_URI = "/v2/deliverables/"
params = {
'order': '000077' # optionally filter by order number
}
response = requests.get(
f"{ALEPH_API_URL}{DELIVERABLES_URI}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
params=params
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
deliverables_list = response.json()
print(json.dumps(deliverables_list, indent=4))
Sample output:
{
"count": 18,
"next": null,
"previous": null,
"results": [
{
"deliverable_id": "deliv.87be4cf1-4a2c-4b00-93b4-ad93354deb36",
"contract": "cont.12345678-6863-4375-a89e-c832b32a5350",
"created_by": null,
"order": "000077",
"status": "PROCESSING",
"footprint": {
"type": "Polygon",
"coordinates": [
[
[
-57.597636904,
-37.953477901
],
...
[
-57.597636904,
-37.953477901
]
]
]
},
"assets": {},
"order_name": "Test Order Rush Tasking",
"activity_outcome_id": "e08c8098-12b8-480d-b154-aae68b5af758",
"processing_level": "L1D_SR",
"created_at": "2025-11-10T19:12:51.562061",
"updated_at": "2025-11-10T19:12:56.630152",
"delivered_at": null,
"rejected_at": null,
"metadata": null,
"tags": [],
"user_email": null,
"latest_event": {
"id": "96454bd1-453c-4b83-8c14-5b3b8d7186fa",
"type": "DeliverableCreated",
"details": {},
"message": "DeliverableCreated event occurred for order 000077",
"timestamp": "2025-11-10T19:12:51.562061Z"
},
"billing_details": null
},
{
"deliverable_id": "deliv.accb1ec3-73fb-4055-a06f-c3bc8429758a",
"contract": "cont.12345678-6863-4375-a89e-c832b32a5350",
"created_by": null,
"order": "000077",
"status": "DELIVERED",
"footprint": {
"type": "Polygon",
"coordinates": [
[
[
-57.597636904,
-37.953477901
],
...
[
-57.597636904,
-37.953477901
]
]
]
},
"assets": {
"visual": {
"href": "https://api.satellogic.com/assets/deliverables/20251110_174836_SN44_L1B_MS_330765/visual?s=s3%3A//satellogic-production-eo-backend-package/quickview/e08c8098-12b8-480d-b154-aae68b5af758/20251110_174836_SN44_L1B_MS_330765/20251110_174836_SN44_L1B_MS_VISUAL.tif",
"type": "image/tiff; application=geotiff",
"roles": [
"data"
]
},
"preview": {
"href": "https://satellogic-production-eo-backend-package.s3.amazonaws.com/quickview/e08c8098-12b8-480d-b154-aae68b5af758/20251110_174836_SN44_L1B_MS_330765/20251110_174836_SN44_L1B_MS_preview.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYWQILZSKMKVTWT42%2F20251110%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20251110T194710Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=fbf80aea5ec2b1fbe9d91146c9f41d92654e3f7312b37917e794745aa894b4da",
"type": "image/png",
"roles": [
"overview"
]
},
"delivery": {
"href": "https://api.satellogic.com/assets/deliverables/20251110_174836_SN44_L1B_MS_330765/delivery?s=s3%3A//satellogic-production-eo-backend-package/quickview/e08c8098-12b8-480d-b154-aae68b5af758/20251110_174836_SN44_L1B_MS_330765/20251110_174836_SN44_L1B_MS_330765.zip",
"type": "application/zip",
"roles": [
"data"
]
},
"thumbnail": {
"href": "https://satellogic-production-eo-backend-package.s3.amazonaws.com/quickview/e08c8098-12b8-480d-b154-aae68b5af758/20251110_174836_SN44_L1B_MS_330765/20251110_174836_SN44_L1B_MS_thumbnail.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAYWQILZSKMKVTWT42%2F20251110%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20251110T194710Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=d6277ef5b1dc54bd144177bfde264c5ef3543e1f1b208ba229d70f0ec0caabb1",
"type": "image/png",
"roles": [
"thumbnail"
]
}
},
"order_name": "Test Order Rush Tasking",
"activity_outcome_id": "e08c8098-12b8-480d-b154-aae68b5af758",
"processing_level": "L1B",
"created_at": "2025-11-10T19:12:51.562061",
"updated_at": "2025-11-10T19:47:12.901694",
"delivered_at": "2025-11-10T19:47:07.540055",
"rejected_at": null,
"metadata": {
"camera": "micro",
"n_bands": -1,
"created_at": "2025-11-10T19:40:19.131212Z",
"exposure_sec": null,
"offnadir_deg": 14.555,
"sun_elevation": 54.0,
"cloud_coverage": 0.06,
"orthorectified": null,
"product_version": "1.8.0",
"gsd": 0.79,
"area_km2": 76.45,
"collection": null,
"scene_id": "20251110_174836_SN44_L1B_MS_330765"
},
"tags": [],
"user_email": null,
"latest_event": {
"id": "b424d41e-a779-4ed2-b321-3917a67255b9",
"type": "DeliverableDelivered",
"details": {
"delivery_method": "API"
},
"message": "DeliverableDelivered event occurred for order 000077",
"timestamp": "2025-11-10T19:44:00Z"
},
"billing_details": {
"billable_sqkm": 76.45,
"billable_sku": "TSKRSH-M.NN.NN"
}
}
]
}
Get successful deliveries within a time range
params = {
'status': 'DELIVERED',
'delivered_at__gt': '2025-11-01T00:00:00Z',
'delivered_at__lt': '2025-11-05T23:59:59Z',
}
response = requests.get(
f"{ALEPH_API_URL}{DELIVERABLES_URI}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
params=params
)
print(f"Status Code: {response.status_code}")
# Raise an error if the request failed
response.raise_for_status()
# Print the JSON response
deliverables_list = response.json()
print(json.dumps(deliverables_list, indent=4))
For deliveries, extract scene_id, delivery time and download links
simplified_deliverables = []
for item in deliverables_list.get('results', []):
simplified_item = {
'scene_id': item.get('metadata', {}).get('scene_id', {}),
'delivered_at': item.get('delivered_at'),
'download_link': item.get('assets', {}).get('delivery', {}).get('href')
}
simplified_deliverables.append(simplified_item)
print("Simplified deliverables:")
print(json.dumps(simplified_deliverables, indent=4))
Sample output:
Simplified deliverables:
[
{
"scene_id": "20251105_091558_SN46_L1B_MS_330765",
"delivered_at": "2025-11-05T11:56:10.744949",
"download_link": "https://api.satellogic.com/assets/deliverables/20251105_091558_SN46_L1B_MS_330765/delivery?s=s3%3A//satellogic-production-eo-backend-package/quickview/47444f8a-3dd1-43a3-9f89-7ac9d613d7dd/20251105_091558_SN46_L1B_MS_330765/20251105_091558_SN46_L1B_MS_330765.zip"
},
{
"scene_id": "20251031_114026_SN46_L1D_SR_MS_330765",
"delivered_at": "2025-11-05T22:35:32.421093",
"download_link": "https://api.satellogic.com/assets/deliverables/20251031_114026_SN46_L1D_SR_MS_330765/delivery?s=s3%3A//satellogic-production-eo-backend-package/l1d-sr/11ff7344-c844-467a-840d-2a76688e88c2/20251031_114026_SN46_L1D_SR_MS_330765/20251031_114026_SN46_L1D_SR_MS_330765.zip"
},
...
{
"scene_id": "20251103_101351_SN46_L1B_MS_330765",
"delivered_at": "2025-11-03T12:55:11.053836",
"download_link": "https://api.satellogic.com/assets/deliverables/20251103_101351_SN46_L1B_MS_330765/delivery?s=s3%3A//satellogic-production-eo-backend-package/quickview/abefde9c-66b2-4b5a-8394-79aceba6c85d/20251103_101351_SN46_L1B_MS_330765/20251103_101351_SN46_L1B_MS_330765.zip"
}
]
Generate an accounting report
Working from the same deliverables output as in Get successful deliveries within a time range, having applied the necessary accounting period (1 week, 1 whole month, current month to date, etc), an accounting report can be built by extracting a subset of keys from the deliverables response and fetching some additional fields from associated order and capture. In this example we'll show how to create a report with the following columns and with a row for each delivery item.
| Contract name | Order name | Order ID | Project name | SKU | Product name | Capture time (if applicable) | Capture ID | Scene ID | Status | Delivered at | Billable quantity |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
import csv
from datetime import datetime
# Report columns
report_columns = [
"contract_name",
"order_name",
"order_id",
"project_name",
"sku",
"product_name",
"capture_time",
"capture_id",
"scene_id",
"status",
"delivered_at",
"billable_quantity"
]
# Define mapping from deliverables to report columns
def extract_deliverable_data(deliverable):
"""Extract data from deliverable dict and map to report columns"""
# Helper function to safely get nested values
def safe_get(d, *keys, default=""):
for key in keys:
try:
d = d[key]
except (KeyError, TypeError, IndexError):
return default
return d if d is not None else default
return {
# Fields populated directly from deliverables dict
"order_name": safe_get(deliverable, 'order_name'),
"order_id": safe_get(deliverable, 'order'),
"capture_id": safe_get(deliverable, 'activity_outcome_id'),
"scene_id": safe_get(deliverable, 'metadata', 'scene_id'),
"delivered_at": safe_get(deliverable, 'delivered_at'),
"billable_quantity": safe_get(deliverable, 'billing_details', 'billable_sqkm'),
"status": safe_get(deliverable, 'status'),
# Fields to be filled from other queries via a pivot field
"contract_name": "", # From order details
"project_name": "", # From order details
"sku": "", # From order details
"product_name": "", # From order details
"capture_time": "", # From captures endpoint
}
# Create list of records from deliverables_list
records = []
for deliverable in deliverables_list.get('results', []):
record = extract_deliverable_data(deliverable)
records.append(record)
# For each record, fetch order and capture details to fill missing fields
for record in records:
# Fetch order details if project_name or product_name is missing
if not record['contract_name'] or not record['project_name'] or not record['sku'] or not record['product_name']:
order_id = record['order_id']
if order_id:
response = requests.get(
f"{ALEPH_API_URL}{ORDERS_URI}{order_id}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
)
if response.status_code == 200:
order_details = response.json()
record['contract_name'] = order_details.get('properties', {}).get('contract_name', record['contract_name'])
record['project_name'] = order_details.get('properties', {}).get('project_name', record['project_name'])
record['sku'] = order_details.get('properties', {}).get('sku', record['sku'])
record['product_name'] = order_details.get('properties', {}).get('product_name', record['product_name'])
# Fetch capture details if capture_time is missing
if not record['capture_time']:
capture_id = record['capture_id']
if capture_id:
response = requests.get(
f"{ALEPH_API_URL}/v2/captures/{capture_id}",
headers={
'authorizationToken': f'Bearer {ACCESS_TOKEN}',
'X-Satellogic-Contract-Id': contract_id
},
)
if response.status_code == 200:
capture_details = response.json()
record['capture_time'] = capture_details.get('properties', {}).get('start', record['capture_time'])
# Reorder dictionary keys to match report_columns order
records = [
{key: record.get(key, "") for key in report_columns}
for record in records
]
# Save to CSV
output_file = 'deliverables_report.csv'
with open(output_file, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=report_columns)
# Write header
writer.writeheader()
# Write rows
writer.writerows(records)
Sample Output: 📥 Download deliverables_report.csv
Once this detailed report is obtained, aggregations can be done to get total billable quantity per contract, per product and per order, for the survey period.