Skip to content

Sampling Design

Designing a statistically valid field sampling campaign requires more than random points. The Batch API exposes a dedicated sampling endpoint that turns staged plot collections into stratified samples that honor travel-time budgets, desired confidence levels, and the carbon pools you plan to measure. This page documents the generation endpoint and how to integrate it in your workflow.

Endpoint

Method Path Purpose
POST /sampling_design/ Generates the sampling and strata layers, launches Earth Engine export jobs, and stores the results.

The endpoint lives behind the same authentication scheme as the rest of the Core/Batch API. It enforces the user's plan limits before any heavy processing starts.

Note: Once the export tasks complete, use the Fetch Samples endpoint to retrieve the sampling design results.

Generate Sampling Design (POST /sampling_design/)

Parameters and Headers

A typical example of a payload for the /sampling_design endpoint is the following:

request_data = {
    "collections": [
        "0x299d006b5658ef3d227b0c3b795b30cf1b33292f5782e6e30f9fb730bf0a173b",
        "0x5dbe602459b0b6dba7dc5fd10aa4ad3ccbd4de3d6d9238d48dd02d6406d5fd78"
    ],
    "start_date": "2017-01-01",
    "date": "2024-12-31",
    "travel_time": 30,
    "confidence_interval": 0.9,
    "margin_of_error": 0.07,
    "isochrone": True,
    "carbon_pool": "agb"
}

With the headers being:

1
2
3
4
headers = {
    'Authorization': "Bearer <authorization_token>",
    'Content-Type': 'application/json'
}

The Authorization header must be replaced by your user token. Check this page for more information on how to authenticate.

Request Body Fields

Field Type Default Description
collections list[str] required Collection IDs or filenames already staged for the user. Multiple entries are merged into a single meta-collection.
start_date str 2017-01-01 Beginning of the monitoring window used for temporal statistics and stratification.
date str current date (clamped to last complete year) End of the monitoring window. Values beyond the last complete calendar year are automatically capped to avoid missing bands.
travel_time int 15 Maximum travel time (minutes) per cluster used when building isochrones.
confidence_interval float 0.95 Target confidence interval for sample counts (typically 0.90, 0.95, or 0.99).
margin_of_error float 0.05 Target margin of error (typically 0.05 or 0.10).
isochrone bool true Whether to enforce the travel-time isochrone constraint for field accessibility.
mean_plot_size float computed from input Average plot size in hectares. If omitted, it is estimated from the supplied collections.
carbon_pool str agb,soc Comma-separated carbon pools to include (agb for above-ground biomass, soc for soil organic carbon, or both).
batch_by_geography bool false Group the plots into geographic clusters and stratify each cluster. One Earth Engine samples task per cluster.
use_dask bool false Run the sampling design as a Prefect flow outside Earth Engine. AGB only: the request fails with 400 when carbon_pool contains soc.

Python

sampling_design.py
import requests
import json

headers = {
    'Authorization': "Bearer <authorization_token>",
    'Content-Type': 'application/json'
}

request_data = {
    "collections": [
        "0x299d006b5658ef3d227b0c3b795b30cf1b33292f5782e6e30f9fb730bf0a173b",
        "0x5dbe602459b0b6dba7dc5fd10aa4ad3ccbd4de3d6d9238d48dd02d6406d5fd78"
    ],
    "start_date": "2017-01-01",
    "date": "2024-12-31",
    "travel_time": 30,
    "confidence_interval": 0.9,
    "margin_of_error": 0.07,
    "isochrone": True,
    "carbon_pool": "agb"
}

response = requests.post(
    "https://epoch-sco2-api.com/sampling_design/",
    json=request_data,
    headers=headers
)

json_result = json.loads(response.content)
print(json_result)

Javascript

sampling_design.js
const axios = require('axios');

const headers = {
    'Authorization': "Bearer <authorization_token>",
    'Content-Type': 'application/json'
};

const requestData = {
    collections: [
        "0x299d006b5658ef3d227b0c3b795b30cf1b33292f5782e6e30f9fb730bf0a173b",
        "0x5dbe602459b0b6dba7dc5fd10aa4ad3ccbd4de3d6d9238d48dd02d6406d5fd78"
    ],
    start_date: "2017-01-01",
    date: "2024-12-31",
    travel_time: 30,
    confidence_interval: 0.9,
    margin_of_error: 0.07,
    isochrone: true,
    carbon_pool: "agb"
};

axios.post("https://epoch-sco2-api.com/sampling_design/", requestData, { headers })
    .then(response => {
        console.log("Sampling design response:", response.data);
    })
    .catch(error => {
        console.error("Error in sampling design request:", error);
    });

Curl

curl -X POST https://epoch-sco2-api.com/sampling_design/ \
  -H "Authorization: Bearer <authorization_token>" \
  -H "Content-Type: application/json" \
  -d '{
        "collections": [
          "0x299d006b5658ef3d227b0c3b795b30cf1b33292f5782e6e30f9fb730bf0a173b",
          "0x5dbe602459b0b6dba7dc5fd10aa4ad3ccbd4de3d6d9238d48dd02d6406d5fd78"
        ],
        "start_date": "2017-01-01",
        "date": "2024-12-31",
        "travel_time": 30,
        "confidence_interval": 0.9,
        "margin_of_error": 0.07,
        "isochrone": true,
        "carbon_pool": "agb"
      }'

Response

The default path launches Earth Engine export tasks. The response returns the task IDs. Monitor the tasks in the Earth Engine task list.

1
2
3
4
response = {
    "samples_task_ids": ["JFGZKQSEPHWEHBOVBDQJH2BK"],  # (1)!
    "strata_task_id": "Q1HA6NK3ZW42F8MQP3L6T9ST",      # (2)!
}
  1. Earth Engine task IDs for the samples export. One task per geographic cluster when batch_by_geography is true. All tasks append to the same _samples table.
  2. Earth Engine task ID for the strata export. All tasks must complete before you fetch results.

With use_dask=true the work runs as a Prefect flow and no Earth Engine task starts. Poll the flow run instead.

1
2
3
4
5
6
7
response = {
    "samples_task_ids": [],
    "strata_task_id": None,
    "flow_run_id": "0f3c2a8e-6b1d-4a5e-9c7f-2d8e1b4a6c3f",  # (1)!
    "flow_run_name": "brisk-otter",
    "n_clusters": None,  # (2)!
}
  1. Prefect flow run ID. Poll the Prefect API for the run state.
  2. Known only after the flow runs.

Retrieving Results

Once the export tasks complete, use the Fetch Samples endpoint to retrieve the sampling design as GeoJSON for use in GIS tools or field data-collection apps.

Have questions or feature requests? Reach out via your Epoch point of contact and include the samples_task_ids (or the flow_run_id for the Prefect path) so we can trace the run quickly.