Skip to content

Fetch and stream inventory data

You are viewing in-progress documentation for v2 (Beta). Switch to the stable version for the current production release.

A tree inventory can hold tens of thousands of stems, so its rows are served in partitions — fetch each partition and stack them into one table. This guide walks that loop.

  1. An API key: my-api-key.

  2. A domain and a completed inventory: your-domain-id and your-inventory-id — e.g. the inventory from Generate a tree inventory from TreeMap.

GET inventory data metadata
curl -X 'GET' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/inventories/your-inventory-id/data/metadata' \
-H 'accept: application/json' \
-H 'api-key: my-api-key'

num_partitions tells you how many data/{partition_index} calls to make; total_rows is the tree count across all of them; columns lists every field each tree row carries.

GET /inventories/{{INVENTORY_ID}}/data/{partition_index}. Each partition is row-oriented: a columns list and a data array of rows, where each row’s values line up with columns.

GET data/0
curl -X 'GET' \
'https://api-v2-prod-nyvjyh5ywa-uw.a.run.app/domains/your-domain-id/inventories/your-inventory-id/data/0' \
-H 'accept: application/json' \
-H 'api-key: my-api-key'

data is shown with three rows above; the real partition holds num_rows (33,415) of them. Each row is [x, y, fia_species_code, fia_status_code, dbh, height, crown_ratio] — coordinates in the domain CRS (meters), dbh in cm, height in m, crown_ratio a 0–1 fraction.

Step 3 — Stream all partitions into a table

Section titled “Step 3 — Stream all partitions into a table”

Loop partition_index from 0 to num_partitions and concatenate:

Fetch all partitions into a DataFrame
import pandas as pd
import requests
API_KEY = "my-api-key"
DOMAIN_ID = "your-domain-id"
INVENTORY_ID = "your-inventory-id"
BASE = "https://api-v2-prod-nyvjyh5ywa-uw.a.run.app"
HEADERS = {"api-key": API_KEY}
# 1. How many partitions? (Each partition is a chunk of rows.)
meta = requests.get(
f"{BASE}/domains/{DOMAIN_ID}/inventories/{INVENTORY_ID}/data/metadata",
headers=HEADERS,
).json()
# 2. Fetch each partition and stack into one DataFrame.
frames = []
for i in range(meta["num_partitions"]):
part = requests.get(
f"{BASE}/domains/{DOMAIN_ID}/inventories/{INVENTORY_ID}/data/{i}",
headers=HEADERS,
).json()
frames.append(pd.DataFrame(part["data"], columns=part["columns"]))
trees = pd.concat(frames, ignore_index=True)
print(len(trees), "trees") # -> 42063 trees
print(trees["dbh"].describe()) # cm; height in m, crown_ratio 0–1
  • Reading only partition 0. A large inventory spans several partitions; data/0 is just the first slice. Iterate to num_partitions or you’ll silently drop trees.
  • Hard-coding column order. Build rows against the columns list in the response rather than assuming a fixed order — it’s there so you don’t have to guess.
  • Inventory not completed. Rows are only available once processing finishes; poll the inventory to completed first.