# openEO Back-End Extractor (`datamule/openeo-process-graph-extractor`) Actor

Point at ANY openEO back-end (the standard API for Earth-observation cloud back-ends — VITO/Terrascope, Copernicus Data Space, EODC). Extract collections, the process registry, capabilities, file formats, service types or UDF runtimes as flat rows + raw JSON. No auth. Pay per record.

- **URL**: https://apify.com/datamule/openeo-process-graph-extractor.md
- **Developed by:** [Datamule](https://apify.com/datamule) (community)
- **Categories:** Developer tools, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 record extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## openEO Back-End Extractor

A generic **"point at any openEO back-end"** extractor.
[openEO](https://openeo.org/) is the open, **uniform REST API** for
**Earth-observation cloud back-ends** — the standard that lets one client talk to
VITO/Terrascope, the Copernicus Data Space Ecosystem, EODC and every other
openEO-conformant processing back-end the same way, over satellite **data cubes**
(Sentinel-1/2/3, Landsat, and hundreds of derived collections).

Because the grammar is uniform across operators, **one actor spans them all.**
Point it at a back-end URL, pick a read mode, and it flattens that back-end's
public discovery documents into clean tabular rows — with the **same normalized
shape regardless of the operator** — plus a lossless `raw` copy of every record.
No per-operator scraper, no authentication.

### How it resolves a back-end

openEO back-ends advertise themselves at `{host}/.well-known/openeo` — a list of
API versions, each with a production flag and a versioned base URL. Give the actor
the **host root** (e.g. `https://openeo.vito.be`) and it resolves the well-known
document to the highest **production** version base for you, then reads the core
discovery endpoints against it. You can also pass an **already-versioned base**
(e.g. `https://openeo.terrascope.be/openeo/1.2`) and skip that step, or pin a
specific version with `apiVersion`.

### Seven read modes

| Mode | What you get (one flat row per…) |
|------|----------------------------------|
| **collections** (default) | …EO data collection (STAC-flavored) — `id`, `title`, `description`, `license`, `keywords`, `extentSpatial` (bbox), `extentTemporal` (interval), `providers`, `raw` |
| **processes** | …process in the back-end's registry — `id`, `title` (summary), `categories`, `parameterCount`, `parameters`, `returns`, `deprecated`, `experimental`, `raw` |
| **capabilities** | the landing document (`id`, `title`, api/backend/stac versions, `production`, advertised `endpoints`) **plus** one row per advertised API version |
| **collection-detail** | …requested collection id — the full STAC Collection incl. `cubeDimensions`, `summaries`, `providers`, extents |
| **file-formats** | …supported input **and** output file format — `id`, `direction`, `title`, `gisDataTypes` |
| **service-types** | …secondary web service type the back-end can publish (WMTS/XYZ/…). *Optional in the spec — processing-only back-ends have none.* |
| **udf-runtimes** | …user-defined-function runtime (Python/R/…) — `id`, runtime `url` (type), available versions in `keywords` |

Every row also carries provenance (`_backend`, `_mode`, `_type`) and the lossless
`raw` source object.

### Input

```json
{
  "backend": "https://openeo.dataspace.copernicus.eu",
  "mode": "collections",
  "collectionId": [],
  "maxItems": 10000
}
```

- **backend** (required) — the URL of any openEO back-end. Host root preferred
  (the actor resolves `/.well-known/openeo`); a versioned base also works.
- **mode** — one of the seven above. Default `collections`.
- **collectionId** — only used by `collection-detail` mode; the collection id(s)
  to fetch full detail for. Run `collections` first to discover the exact ids.
- **apiVersion** — optionally pin the openEO API version (e.g. `1.2.0`); defaults
  to the highest production version advertised.
- **maxItems** — total row cap (each row is one billable event). Default 10000.
- **bearerToken** / **extraHeaders** — optional; **not required** — every read
  mode targets public, unauthenticated discovery endpoints. Never logged.

### Output (collections mode, example row)

```json
{
  "_backend": "https://openeo.dataspace.copernicus.eu/openeo/1.2",
  "_mode": "collections",
  "_type": "collection",
  "id": "SENTINEL3_OLCI_L1B",
  "title": "Sentinel 3 OLCI",
  "license": "proprietary",
  "keywords": null,
  "extentSpatial": [[-180.0, -85.0, 180.0, 85.0]],
  "extentTemporal": [["2016-04-17T11:33:13Z", null]],
  "stacVersion": "1.0.0",
  "raw": { "…": "the full STAC Collection" }
}
```

### Behaviour & honesty

- **Version resolution is automatic.** The well-known document is parsed to the
  best production version base; an already-versioned base is used as-is.
- **STAC collections are flattened** (id/title/description/license/extents) with
  the full STAC Collection preserved in `raw` — nothing is lost.
- **Pagination handled.** `collections` and `processes` auto-follow the top-level
  `rel="next"` link (relative or absolute) until exhausted or the cap is reached.
- **Optional endpoints degrade gracefully.** `service_types` / `udf_runtimes` are
  optional in the openEO spec; a back-end that doesn't offer one is reported, not
  crashed.
- **Zero records is never faked.** If the chosen mode returns nothing (an optional
  endpoint the back-end doesn't serve, or an unknown collection id), the run exits
  non-zero instead of emitting fabricated rows.

### Pricing

Pay-per-event: one **record** charge per row returned.

### Verified

Tested live against three independent operators — **VITO/Terrascope**
(`openeo.vito.be` → 89 collections / 150 processes), **Copernicus Data Space
Ecosystem** (`openeo.dataspace.copernicus.eu` → 83 / 143) and **EODC**
(`openeo.eodc.eu`) — confirming identical normalized output across back-ends.

# Actor input Schema

## `backend` (type: `string`):

The URL of ANY openEO back-end — the standard REST API for Earth-observation cloud back-ends. Pass the host root and the actor resolves /.well-known/openeo to the production version base for you. Examples: https://openeo.vito.be (VITO/Terrascope), https://openeo.dataspace.copernicus.eu (Copernicus Data Space Ecosystem), https://openeo.eodc.eu (EODC). An already-versioned base like https://openeo.terrascope.be/openeo/1.2 also works.

## `mode` (type: `string`):

Which public discovery document to extract. collections = one row per EO data collection (STAC-flavored, the usual choice). processes = the back-end's process registry. capabilities = the back-end landing document + advertised API versions. collection-detail = the full STAC Collection for specific ids (set Collection id(s)). file-formats = supported input/output formats. service-types = secondary web service types (optional; processing-only back-ends have none). udf-runtimes = user-defined-function runtimes (Python/R/…).

## `collectionId` (type: `array`):

One or more EO collection ids to fetch full detail for, e.g. SENTINEL2\_L2A, SENTINEL1\_GRD. ONLY used by collection-detail mode. Run collections mode first to discover the exact ids this back-end serves. Ignored by every other mode.

## `apiVersion` (type: `string`):

Optionally pin which openEO API version to read, e.g. 1.2.0. When empty the actor picks the highest production version advertised at /.well-known/openeo. Ignored if you passed an already-versioned base URL.

## `maxItems` (type: `integer`):

Maximum total number of rows to emit (the actor auto-paginates collections/processes until this cap or the result set is exhausted). Each returned row is one billable event. Default 10000.

## `bearerToken` (type: `string`):

Optional OAuth2 bearer token. NOT required — all read modes here target PUBLIC discovery endpoints that need no authentication. Sent as Authorization: Bearer \*\*\*. Never logged.

## `extraHeaders` (type: `object`):

Optional extra HTTP headers to send with every request, as a JSON object. Leave empty for public back-ends.

## Actor input object example

```json
{
  "backend": "https://openeo.dataspace.copernicus.eu",
  "mode": "collections",
  "maxItems": 10000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "backend": "https://openeo.dataspace.copernicus.eu",
    "maxItems": 10000
};

// Run the Actor and wait for it to finish
const run = await client.actor("datamule/openeo-process-graph-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "backend": "https://openeo.dataspace.copernicus.eu",
    "maxItems": 10000,
}

# Run the Actor and wait for it to finish
run = client.actor("datamule/openeo-process-graph-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "backend": "https://openeo.dataspace.copernicus.eu",
  "maxItems": 10000
}' |
apify call datamule/openeo-process-graph-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=datamule/openeo-process-graph-extractor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/QjFgJyeyhtV6qh2mn/builds/Hu542RPAS08QAa8vb/openapi.json
