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

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 POST call launches two Earth Engine export tasks. The response returns task IDs so you can track progress via Earth Engine or the SCo2-API task status endpoint.

1
2
3
4
response = {
    "samples_task_id": "JFGZKQSEPHWEHBOVBDQJH2BK",  # (1)!
    "strata_task_id": "Q1HA6NK3ZW42F8MQP3L6T9ST"   # (2)!
}
  1. Earth Engine task ID for the samples export job. Use this to monitor progress in Earth Engine or via the task status endpoint.
  2. Earth Engine task ID for the strata export job. Both tasks must complete before fetching results.

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_id so we can trace the run quickly.