Bring your data into E2
Normalize user-owned observations, attach them to a known feature, store them locally, and create a portable data file.
Documentation navigation
Start with E2
SDK guides
CLI guides
MCP guides
Applications
Framework quickstarts
Upload a dataset
upload.ts
import { StorageClient } from "@embed-earth/sdk-test/node";
const result = await new StorageClient().upload({
path: "./observations.csv",
database: "./e2.db",
connectTo: "restaurant",
output: "./observations.geoparquet",
});
console.log(result.rows, result.geoparquetPath);Every row must resolve to an existing E2 feature. Use
feature, connectTo, an explicit featureId, or existing row metadata.Accepted input and options
| Input | Required row data | Notes |
|---|---|---|
| GeoJSON / GeoJSON FeatureCollection | geometry or lat/lng | Properties are preserved. |
| CSV | lat + lng, or latitude + longitude | The first row is treated as headers. |
| Parquet | lat/lng and feature metadata | Rows are read and normalized before indexing. |
Optional upload settings include source, region, and observedAt. An existing valid e2_id is retained when its feature matches; otherwise the SDK creates a cell at spatial resolution 10 and temporal resolution 1d.
Normalized rows
row.json
{
"feature_id": 101,
"feature": "restaurant",
"e2_id": "e2:1:...:1d:...:101",
"lat": 40.74,
"lng": -73.99,
"geometry": { "type": "Point", "coordinates": [-73.99, 40.74] },
"observed_at": "2026-08-18T09:00:00.000Z",
"source": "user",
"properties": {}
}The result includes the number of imported rows, resolved feature key and ID, database path, and output file path.
Query the database
local.ts
import { LocalDatabase } from "@embed-earth/sdk-test/node";
const db = await LocalDatabase.open("./e2.db");
const rows = db.query({ feature: "restaurant", window: "30d", limit: 100 });
const stats = db.stats();
db.close();