Purchasing Catalog Images
This page describes how to create an order for catalog images, complete the payment via Stripe, and manage existing orders through the API.
NOTE
All endpoints require a valid bearer token. See the Authentication page for details.
Create an Order
Creates a new order for one or more catalog images. The order will be in UNPAID status until payment is completed.
Endpoint
POST https://app.open-cosmos.com/api/data/v0/order/orders
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
redirect_host | string | No | Override the default redirect URL after checkout completion. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "IMAGE" for catalog purchases. |
data | object | Yes | Contains the order_line_items array. |
data.order_line_items | array | Yes | Array of items to purchase (see below). |
organisation | integer | Yes | Your organisation's numeric ID. |
contract_id | integer | Yes | The contract ID for this purchase. |
licenses | array | Yes | Array of licenses the user accepts (see below). |
Order Line Item fields:
| Field | Type | Required | Description |
|---|---|---|---|
collection | string | Yes | The STAC collection ID. |
item | string | Yes | The STAC item ID. |
level | string | Yes | The processing level (e.g. L2A). |
geometry | object | No | A GeoJSON geometry object for sub-area purchases. Must be paired with project_id. |
project_id | string | No | The project ID to associate the item with. Must be paired with geometry. |
NOTE
The geometry and project_id fields must either both be provided or both be omitted. You cannot set one without the other.
License fields:
| Field | Type | Required | Description |
|---|---|---|---|
license_link | string | Yes | URL to the full license text. |
license_name | string | Yes | The name of the license. |
license_version | string | Yes | The version of the license. |
accepted | boolean | Yes | Must be true to proceed with the order. |
Response
The response includes the created order with a unique ID, status, computed prices for each line item, and a checkout URL if payment is required.
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "IMAGE",
"customer_id": "cus-abc123",
"organisation_id": 42,
"contract_id": 456,
"status": "UNPAID",
"payment_method": "CARD",
"payment_reference_number": "",
"order_line_items": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"collection": "sentinel-2-l2a",
"item": "S2A_MSIL2A_20230615T100559_N0509_R022_T33UUP_20230615T135959",
"level": "L2A",
"geometry": null,
"project_id": null,
"price": {
"value": "150.00",
"discount": "0",
"final": "150.00",
"currency": "USD"
},
"licenses": [
{
"license_link": "https://example.com/license/eula-v1",
"license_name": "DataCosmos EULA",
"license_version": "1.0",
"accepted": true
}
],
"is_downloaded": false,
"delivered": false,
"paid": false,
"visualized_count": 0,
"downloaded_count": 0
}
],
"checkout_redirect_url": "https://checkout.stripe.com/c/pay/cs_test_...",
"created_by": "google-apps|user@example.com",
"created_at": "2026-01-21T12:00:00Z",
"updated_at": "2026-01-21T12:00:00Z"
}
}
Examples
Bash
curl --request POST "https://app.open-cosmos.com/api/data/v0/order/orders" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"type": "IMAGE",
"data": {
"order_line_items": [
{
"collection": "sentinel-2-l2a",
"item": "S2A_MSIL2A_20230615T100559_N0509_R022_T33UUP_20230615T135959",
"level": "L2A"
}
]
},
"organisation": 42,
"contract_id": 456,
"licenses": [
{
"license_link": "https://example.com/license/eula-v1",
"license_name": "DataCosmos EULA",
"license_version": "1.0",
"accepted": true
}
]
}'
Python
import requests
# Get bearer token and add to session (see Authentication docs)
order_payload = {
"type": "IMAGE",
"data": {
"order_line_items": [
{
"collection": "sentinel-2-l2a",
"item": "S2A_MSIL2A_20230615T100559_N0509_R022_T33UUP_20230615T135959",
"level": "L2A",
}
]
},
"organisation": 42,
"contract_id": 456,
"licenses": [
{
"license_link": "https://example.com/license/eula-v1",
"license_name": "DataCosmos EULA",
"license_version": "1.0",
"accepted": True,
}
],
}
response = session.post(
"https://app.open-cosmos.com/api/data/v0/order/orders",
json=order_payload,
)
order = response.json()
print(f"Order ID: {order['data']['id']}")
print(f"Status: {order['data']['status']}")
print(f"Checkout URL: {order['data']['checkout_redirect_url']}")
Purchasing Multiple Items in a Single Order
You can include multiple items in the order_line_items array to purchase them together in a single order:
order_payload = {
"type": "IMAGE",
"data": {
"order_line_items": [
{
"collection": "sentinel-2-l2a",
"item": "S2A_MSIL2A_20230615T100559_N0509_R022_T33UUP_20230615T135959",
"level": "L2A",
},
{
"collection": "sentinel-2-l2a",
"item": "S2A_MSIL2A_20230620T101021_N0509_R022_T33UUP_20230620T140000",
"level": "L2A",
},
]
},
"organisation": 42,
"contract_id": 456,
"licenses": [
{
"license_link": "https://example.com/license/eula-v1",
"license_name": "DataCosmos EULA",
"license_version": "1.0",
"accepted": True,
}
],
}
response = session.post(
"https://app.open-cosmos.com/api/data/v0/order/orders",
json=order_payload,
)
order = response.json()
for item in order["data"]["order_line_items"]:
print(f"Item: {item['item']} — Price: {item['price']['final']} {item['price']['currency']}")
Initiate Checkout
After creating an order, you need to complete payment. This endpoint creates a Stripe checkout session and returns a URL where the user can enter payment details.
Endpoint
GET https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}/checkout
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | UUID | Yes | The order ID returned from the create order response. |
Response
{
"data": {
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_..."
}
}
NOTE
If the order creation response already includes a checkout_redirect_url, you can use that URL directly without calling this endpoint separately. This endpoint is useful when you need to generate a new checkout session for an existing unpaid order.
Examples
Bash
ORDER_ID="550e8400-e29b-41d4-a716-446655440000"
curl --request GET "https://app.open-cosmos.com/api/data/v0/order/orders/${ORDER_ID}/checkout" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session (see Authentication docs)
order_id = "550e8400-e29b-41d4-a716-446655440000"
response = session.get(
f"https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}/checkout",
)
checkout_data = response.json()
checkout_url = checkout_data["data"]["checkout_url"]
print(f"Complete payment at: {checkout_url}")
Get Order Details
Retrieves the full details of a specific order, including its current status and line items.
Endpoint
GET https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | UUID | Yes | The ID of the order to retrieve. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
expand | string | No | Comma-separated list of fields to expand. Supported: credits_used. |
Response
Returns a full OrderResponse object (same structure as the create order response).
Examples
Bash
ORDER_ID="550e8400-e29b-41d4-a716-446655440000"
curl --request GET "https://app.open-cosmos.com/api/data/v0/order/orders/${ORDER_ID}" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session (see Authentication docs)
order_id = "550e8400-e29b-41d4-a716-446655440000"
response = session.get(
f"https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}",
)
order = response.json()
print(f"Order status: {order['data']['status']}")
Polling for Payment Completion
After redirecting the user to the Stripe checkout page, you can poll the order status to detect when payment has been completed:
import time
import requests
# Get bearer token and add to session (see Authentication docs)
order_id = "550e8400-e29b-41d4-a716-446655440000"
max_attempts = 30
poll_interval_seconds = 10
for attempt in range(max_attempts):
response = session.get(
f"https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}",
)
order = response.json()
status = order["data"]["status"]
if status == "PAID":
print("Payment completed successfully!")
break
elif status == "CANCELLED":
print("Order was cancelled.")
break
else:
print(f"Status: {status} — waiting {poll_interval_seconds}s...")
time.sleep(poll_interval_seconds)
List Orders
Retrieves a list of your orders, optionally filtered by order IDs.
Endpoint
GET https://app.open-cosmos.com/api/data/v0/order/orders
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | UUID[] | No | One or more order IDs to filter by. Can be repeated for multiple IDs. |
Response
Returns an array of OrderResponse objects.
Examples
Bash
# List all orders
curl --request GET "https://app.open-cosmos.com/api/data/v0/order/orders" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
# Filter by specific order IDs
curl --request GET "https://app.open-cosmos.com/api/data/v0/order/orders?order_id=550e8400-e29b-41d4-a716-446655440000&order_id=660f9500-f30c-52e5-b827-557766551111" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}"
Python
import requests
# Get bearer token and add to session (see Authentication docs)
# List all orders
response = session.get(
"https://app.open-cosmos.com/api/data/v0/order/orders",
)
orders = response.json()
for order in orders["data"]:
print(f"Order {order['id']}: {order['status']}")
Update or Cancel an Order
Updates an existing order's status or payment method. This can be used to cancel an unpaid order or change the payment method.
Endpoint
PATCH https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
order_id | UUID | Yes | The ID of the order to update. |
Request Body
All fields are optional. Only include the fields you want to update.
| Field | Type | Description |
|---|---|---|
status | string | New status: UNPAID, PAID, or CANCELLED. |
payment_method | string | New payment method: BANK_TRANSFER, CARD, or NOT_REQUIRED. |
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Examples
Cancel an order (Bash)
ORDER_ID="550e8400-e29b-41d4-a716-446655440000"
curl --request PATCH "https://app.open-cosmos.com/api/data/v0/order/orders/${ORDER_ID}" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${DATACOSMOS_ACCESS_TOKEN}" \
--data-raw '{
"status": "CANCELLED"
}'
Cancel an order (Python)
import requests
# Get bearer token and add to session (see Authentication docs)
order_id = "550e8400-e29b-41d4-a716-446655440000"
response = session.patch(
f"https://app.open-cosmos.com/api/data/v0/order/orders/{order_id}",
json={"status": "CANCELLED"},
)
result = response.json()
print(f"Order {result['data']['id']} has been cancelled.")
Error Responses
All ordering endpoints return errors in a consistent format:
{
"errors": [
{
"type": "invalid_input",
"message": "order line item must have collection, item and level",
"field": "order_line_item",
"source": "order-service",
"trace_id": "abc123def456"
}
]
}
Common Error Codes
| HTTP Status | Type | Description |
|---|---|---|
400 | invalid_input | The request body or parameters are invalid. |
401 | unauthorized | Missing or invalid bearer token. |
403 | forbidden | You do not have permission to access this resource. |
404 | not_found | The specified order or item was not found. |
500 | internal_error | An unexpected server error occurred. |
Where to Next
← Pricing API | API Reference →