How to publish STAC data at eodc

This guide explains how customers can publish and manage their own data in the eodc-hosted STAC API endpoint (https://cstac.services.eodc.eu/stac). The typical workflow consists of preparing STAC metadata, authenticating to the API, and creating STAC Collections and Items.

Prerequisites

  • Valid eodc user credentials to authenticate against the STAC API.

  • Your dataset described using valid STAC metadata:

    • Collection – describes a dataset

    • Items – describe individual scenes or data entries

    • Assets – links to the actual data files

Example structure:

dataset/
 ├── collection.json
 └── items/
      ├── item_001.json
      ├── item_002.json
      └── ...

Ready-to-use sample data is available in the eodc-examples GitHub repository, if you want to try the workflow before ingesting your own data.

Access control

Some metadata fields are required by the STAC catalogue. In particular, the access field defines who can see the data.

Example: visible to all users in an organisation

{
  "access": {
    "visibility": "organisation",
    "allowed_users": [],
    "allowed_organisations": ["eodc"]
  }
}

Example: visible only to specific users

{
  "access": {
    "visibility": "user",
    "allowed_users": ["john.smith@eodc.eu", "jane.smith@eodc.eu"],
    "allowed_organisations": []
  }
}

If the access field is missing or configured incorrectly, the data may not be visible in the catalogue.

Authenticate

from getpass import getpass
from eodc_connect.auth import EODCConnection
import requests

username = input("Enter your eodc username: ")
password = getpass("Enter your eodc password: ")

conn = EODCConnection(username=username, password=password)
token = conn.get_access_token()

HEADERS = {
    "Authorization": f"Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

Create a Collection

WRITE_BASE = "https://cstac.services.eodc.eu/stac"

url = f"{WRITE_BASE}/collections"
r = requests.post(url, headers=HEADERS, json=collection)
r.raise_for_status()

Create Items

items_url = f"{WRITE_BASE}/collections/{collection_id}/items"

for item in items:
    r = requests.post(items_url, headers=HEADERS, json=item)
    r.raise_for_status()

Update an Item

Existing STAC Items can be updated using a PUT request:

  1. Retrieve the current Item with GET

  2. Modify the desired fields (e.g. metadata or assets)

  3. Replace the Item via PUT

item_url = f"{WRITE_BASE}/collections/{collection_id}/items/{item_id}"

r = requests.get(item_url, headers=HEADERS)
r.raise_for_status()
current = r.json()

current.setdefault("properties", {})
current["properties"]["updated"] = "2026-07-21T12:00:00Z"

r = requests.put(item_url, headers=HEADERS, json=current)
r.raise_for_status()

Delete a Collection

del_url = f"{WRITE_BASE}/collections/{collection_id}"
r = requests.delete(del_url, headers=HEADERS)
r.raise_for_status()

Common mistakes

Missing access metadata — if the access field is missing, the dataset may not be visible to other users.

Invalid STAC structure — make sure the metadata follows the STAC specification. The stac-validator tool can help catch issues before ingestion:

stac-validator collection.json

Incorrect asset links — assets must point to valid and accessible data files.

Troubleshooting

Item creation fails — check that the collection exists, item IDs are unique, and the metadata is valid JSON.

Data not visible in the catalogue — check the access settings, organisation name, and permissions.

Validation errors — run a STAC validator before ingestion.

Support

If you encounter problems publishing STAC data at eodc, please contact support@eodc.eu.

Worked example

See the Customer STAC ingestion notebook for a full runnable walkthrough — authenticating, loading sample data, creating a Collection and Items, updating an Item, and cleaning up.