Skip to content

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))
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.