# API Usage — Petrel Flow Accumulation Layer v0.1 The Petrel Flow Accumulation Layer v0.1 is delivered through the Petrel API. Every download is authenticated; downloads are rate-limited per account tier. ## Authentication You need a Petrel account and an API key: 1. Sign up at https://petreldata.io/signup (free tier available) 2. Generate an API key under your account settings 3. Export it as `PETREL_API_KEY` in your shell environment ```bash export PETREL_API_KEY=pk_live_... ``` ## Endpoints (v1 stable) | Endpoint | Method | Description | |---|---|---| | `/v1/layer/flow_accumulation` | GET | List available flow-accumulation vintages | | `/v1/layer/flow_accumulation/v0.1_global_dem` | GET | Layer manifest (STAC item + docs) | | `/v1/layer/flow_accumulation/v0.1/bundle` | GET | Request signed URL for the full layer download (rate-limited) | ## Rate limits | Tier | Bundle downloads | Metadata | |---|---|---| | Free | 10 / day | 1000 / minute | | Researcher | 100 / day | unlimited | | Commercial | per contract | unlimited | ## Code snippets ### curl — full bundle download ```bash # 1. Get the signed-URL manifest (URLs valid for 1 hour) curl -s -H "X-API-Key: $PETREL_API_KEY" \ https://api.petreldata.io/v1/layer/flow_accumulation/v0.1/bundle > bundle.json # 2. Download both layer files for n in flow_distance_to_drainage_278m.tif flow_twi_278m.tif; do jq -r --arg n "$n" '.files[] | select(.name==$n) | .url' bundle.json \ | xargs -I{} curl -s "{}" -o "$n" done ``` ### Python — point query (distance to drainage) ```python import os, requests, rasterio api_key = os.environ["PETREL_API_KEY"] r = requests.get( "https://api.petreldata.io/v1/layer/flow_accumulation/v0.1/bundle", headers={"X-API-Key": api_key}, ).json() urls = {f["name"]: f["url"] for f in r["files"]} # 1-hour presigned URLs lat, lon = -8.108, 112.922 # Semeru summit, Java with rasterio.open(urls["flow_distance_to_drainage_278m.tif"]) as src: raw = next(src.sample([(lon, lat)]))[0] scale = float(src.tags()["PETREL_SCALE"]) if raw == src.nodata: print("no data (ocean / outside coverage)") else: print(f"distance to drainage: {raw * scale:.0f} m (0 = on a channel)") ``` ### Python — read the topographic wetness index ```python with rasterio.open(urls["flow_twi_278m.tif"]) as src: raw = next(src.sample([(lon, lat)]))[0] scale = float(src.tags()["PETREL_SCALE"]) twi = None if raw == src.nodata else raw * scale print("TWI:", f"{twi:.2f}" if twi is not None else "NoData", "(high = wet/valley floor, low = steep/well-drained)") ``` ### Python — windowed read over HTTPS You don't need to download the full layer if you only want a region. `rasterio` can stream-open a COG directly: ```python import os, requests import rasterio from rasterio.windows import from_bounds api_key = os.environ["PETREL_API_KEY"] r = requests.get( "https://api.petreldata.io/v1/layer/flow_accumulation/v0.1/bundle", headers={"X-API-Key": api_key}, ).json() urls = {f["name"]: f["url"] for f in r["files"]} # 1-hour presigned URLs # Distance to drainage over eastern Java with rasterio.open(urls["flow_distance_to_drainage_278m.tif"]) as src: win = from_bounds(111, -9, 115, -6, transform=src.transform) raw = src.read(1, window=win) scale = float(src.tags()["PETREL_SCALE"]) dist_m = raw * scale # physical; 65535*scale = NoData ``` ### R — windowed read (using `terra`) ```r library(terra) api_key <- Sys.getenv("PETREL_API_KEY") manifest <- httr::GET( "https://api.petreldata.io/v1/layer/flow_accumulation/v0.1/bundle", httr::add_headers(`X-API-Key` = api_key) ) files <- httr::content(manifest)$files r <- rast(Filter(function(f) f$name == "flow_distance_to_drainage_278m.tif", files)[[1]]$url) java <- crop(r, ext(111, 115, -9, -6)) plot(java) ``` ### QGIS / ArcGIS For desktop GIS use: 1. Download via the bundle endpoint (Petrel API key required) 2. Open the `.tif` directly in QGIS/ArcGIS — internal tiling and overviews are honored 3. The STAC item (`/v1/layer/flow_accumulation/v0.1_global_dem` → STAC JSON) can be used with STAC plugins for automated discovery ## Layer encoding reference Both layers are uint16 with a linear scale factor recorded in the `PETREL_SCALE` file tag — multiply the raw integer by it to get physical values (`physical = raw × PETREL_SCALE`). | File | Dtype | PETREL_SCALE | Physical unit / range | NoData | |---|---|---|---|---| | `flow_distance_to_drainage_278m.tif` | uint16 | ≈ 0.763 | metres, 0–50 000 | 65535 | | `flow_twi_278m.tif` | uint16 | ≈ 5.341 × 10⁻⁴ | TWI (dimensionless), ~0–35 | 65535 | Always read the scale from the file tag rather than hard-coding it. **Interpretation reminder:** `flow_distance_to_drainage` is metres to the nearest channel (0 = on a channel; the far tail is capped at 50 km). `flow_twi` is the topographic wetness index — high on flat, water-gathering terrain, low on steep, well-drained slopes. In v0.1 use the drainage **network structure**, not absolute accumulation — see [`model_card.md`](model_card.md). ## Errors and rate-limit behavior The API returns standard HTTP status codes: - `401 Unauthorized` — missing or invalid API key - `403 Forbidden` — license tier doesn't permit this endpoint - `429 Too Many Requests` — rate limit exceeded; response includes `Retry-After` header and `X-RateLimit-Reset` timestamp - `404 Not Found` — vintage or layer not recognized - `503 Service Unavailable` — temporary backend issue; safe to retry with exponential backoff ## Support - **Documentation:** https://petreldata.io/docs/layers/flow_accumulation - **API status:** https://status.petreldata.io - **Bugs / questions:** layers@petreldata.io - **Commercial inquiries:** licensing via https://petreldata.io/demo