# API Usage — Petrel Aridity Index Layer v0.1 The Petrel Aridity Index 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 # Petrel keys look like tlk.. — copy yours from # https://petreldata.io/account#api-keys export PETREL_API_KEY=tlk.1a2b3c4d-5e6f-7890-abcd-ef1234567890.xxxxxxxx ``` ## Endpoints (v1 stable) | Endpoint | Method | Description | |---|---|---| | `/v1/layer/aridity` | GET | List available aridity vintages | | `/v1/layer/aridity/v0.1_global_ml` | GET | Layer manifest (STAC item + docs) | | `/v1/layer/aridity/v0.1/bundle` | GET | Request signed URL for the full layer download (rate-limited) | ## Quotas Your plan's monthly allowance is shared across the API; the authoritative figures live at https://petreldata.io/pricing. | Plan | Included lookups / month | Beyond the quota | |---|---|---| | Free | 1,000 | requests return HTTP 429 `quota_exceeded`; nothing is charged | | Indie | 10,000 | overage billed per lookup if you enable it | | Growth | 50,000 | overage billed per lookup if you enable it | | Scale | 250,000 | overage billed per lookup if you enable it | Overage is off until you turn it on (Account -> Billing). A short burst limit also applies per key, so batch your requests rather than firing them in parallel bursts. ## 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/aridity/v0.1/bundle > bundle.json # 2. Download all 3 layer files for f in index class index_ci; do n="aridity_${f}_0p25deg.tif" jq -r --arg n "$n" '.files[] | select(.name==$n) | .url' bundle.json \ | xargs -I{} curl -s "{}" -o "$n" done ``` ### Python — point query ```python import os, requests, rasterio api_key = os.environ["PETREL_API_KEY"] r = requests.get( "https://api.petreldata.io/v1/layer/aridity/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 = 24.71, 46.68 # Riyadh with rasterio.open(urls["aridity_index_0p25deg.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"aridity index P/PET: {raw * scale:.3f} (low = arid, high = humid)") ``` ### Python — read the UNEP class directly ```python UNEP = {1: "hyper-arid", 2: "arid", 3: "semi-arid", 4: "dry-subhumid", 5: "humid"} with rasterio.open(urls["aridity_class_0p25deg.tif"]) as src: code = int(next(src.sample([(lon, lat)]))[0]) # uint8; 0 = ocean/NoData print("class:", UNEP.get(code, "ocean / NoData")) ``` ### 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/aridity/v0.1/bundle", headers={"X-API-Key": api_key}, ).json() urls = {f["name"]: f["url"] for f in r["files"]} # 1-hour presigned URLs # Aridity index over the Mediterranean / North Africa with rasterio.open(urls["aridity_index_0p25deg.tif"]) as src: win = from_bounds(-10, 30, 40, 47, transform=src.transform) raw = src.read(1, window=win) scale = float(src.tags()["PETREL_SCALE"]) ai = 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/aridity/v0.1/bundle", httr::add_headers(`X-API-Key` = api_key) ) files <- httr::content(manifest)$files r <- rast(Filter(function(f) f$name == "aridity_index_0p25deg.tif", files)[[1]]$url) med <- crop(r, ext(-10, 40, 30, 47)) plot(med) ``` ### 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/aridity/v0.1_global_ml` → STAC JSON) can be used with STAC plugins for automated discovery ## Layer encoding reference The two continuous 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`). The class layer is uint8 (no scale). | File | Dtype | PETREL_SCALE | Physical unit / range | NoData | |---|---|---|---|---| | `aridity_index_0p25deg.tif` | uint16 | ≈ 6.104 × 10⁻⁵ | P/PET, 0–4 | 65535 | | `aridity_class_0p25deg.tif` | uint8 | — (class code) | UNEP class 1–5 | 0 | | `aridity_index_ci_0p25deg.tif` | uint16 | ≈ 1.526 × 10⁻⁵ | 90% CI half-width, 0–1 | 65535 | Always read the scale from the file tag rather than hard-coding it. **Interpretation reminder:** the index is **P/PET** — a *high* value means a *wet* (low-aridity) cell, a *low* value means a dry one. Use `aridity_class` for the named UNEP class. Native resolution is ~28 km (0.25°); do not treat resampled derivatives as adding information. ## 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/aridity - **API status:** https://status.petreldata.io - **Bugs / questions:** layers@petreldata.io - **Commercial inquiries:** licensing via https://petreldata.io/demo