Continuuiti

API Documentation

Programmatic access to Continuuiti's geospatial intelligence platform

API Access

Every Continuuiti account includes a personal API key. Trigger analyses on any module, run free sandbox requests with "dry_run": true, and retrieve all your results programmatically.

Get your key on the Platform API page.

Available APIs

Geocoder API

Convert addresses to geographic coordinates with quality validation and batch processing.

LULC+ API

Land use and land cover analysis with satellite imagery and change detection.

Climate Risk API

Physical climate hazard assessment with 12 risk factors across multiple scenarios.

Damage Estimation API

Flood damage estimates using HAZUS and JRC depth-damage curves for single or batch buildings.

Flood Depth API retired

Retired 2026-10-21. Existing jobs, results and exports stay readable; submissions return 410. New work: the Riverine & Coastal API.

CDEM API

Bare-earth terrain, building footprints and road centrelines for a coordinate, as one site bundle.

Riverine & Coastal API

The JRC riverine and WRI Aqueduct coastal depth fields over a 6 km box, four return periods, present-day values, raw with per-band audits.

Hazard History API

Historical flood episodes and landslide events per coordinate — 2.6M flood events, 50K landslides.

View Endpoints

Carbon Project Screening API

ARR + REDD+ Go/No-Go screening on polygon parcels with bundled climate risk.

View Endpoints

Authentication

All API requests require an API key passed in the request header:

HTTP Header
X-API-Key: YOUR_API_KEY

Your personal sk_live_ key is on the Platform API page — copy it from there and regenerate it any time.

Pricing

API calls consume credits from your account balance.

API Credits per Request
Geocoder 1 credit per address
LULC+ 1 credit per location
Climate Risk 1 credit per location
Damage Estimation 1 credit per building
Flood Depth Retired 2026-10-21; reads only, no charge
Hazard History 1 credit per location (floods + landslides bundled)
CDEM 1 credit per site bundle
Riverine & Coastal (flood field) 1 credit per site, covering both fields
Carbon Project Screening 1 credit per parcel

Sandbox requests ("dry_run": true) are free and never consume credits. Sandbox batches complete immediately: the submit response reports COMPLETED and results are available right away, with no polling needed. Some modules apply a lower batch size cap to sandbox batches (Climate Risk: 200). Contact support for enterprise pricing and volume discounts.

Base URL

https://api.continuuiti.com/api/v1/

Geocoder API

Convert addresses to geographic coordinates

Overview

The Geocoder API converts text addresses to geographic coordinates (latitude/longitude). It includes built-in quality validation to reject garbage inputs, saving API quota and providing immediate feedback on data quality. Supports both single address geocoding and batch processing for up to 5,000 addresses.

Endpoints

POST /api/v1/geocode/

Geocode a single address to coordinates.

Request
{
  "address": "1600 Amphitheatre Parkway, Mountain View, CA"
}
Response (201 Created)
{
  "id": 1,
  "original_address": "1600 Amphitheatre Parkway, Mountain View, CA",
  "formatted_address": "Google Building 41, 1600, Amphitheatre Parkway...",
  "latitude": "37.4224857",
  "longitude": "-122.0855846",
  "quality": {
    "score": 0.72,
    "status": "PASSED",
    "issues": [],
    "match_type": "building"
  }
}
POST /api/v1/geocode/batch/

Submit a batch of addresses for geocoding (max 5,000 addresses).

Request
{
  "addresses": [
    {"address": "1600 Amphitheatre Parkway, Mountain View, CA", "label": "Google HQ"},
    {"address": "1 Infinite Loop, Cupertino, CA", "label": "Apple HQ"}
  ]
}
Response (200 OK)
{
  "batch_id": "batch_geocode_a1b2c3d4",
  "status": "COMPLETED",
  "total_count": 2,
  "completed": 2,
  "failed": 0,
  "rejected": 0
}
GET /api/v1/geocode/batch/{batch_id}/

Get batch status and progress.

GET /api/v1/geocode/batch/{batch_id}/results/

Get paginated geocoding results.

Quality Validation

Addresses are validated before geocoding to reject clearly unusable inputs. Rejected addresses are marked with status: "REJECTED" and don't consume geocoding quota.

Need help? Contact us at support@continuuiti.com

LULC+ API

Land use and land cover analysis

Overview

The LULC+ API provides annual satellite composites and land cover classification for any geographic location. Processing is asynchronous - you submit a job, then poll for results. Returns RGB satellite imagery, land cover classification maps, and statistical analysis of land cover changes over time.

Imagery

Sentinel-2 Surface Reflectance

Classification

Dynamic World Land Cover

Endpoints

POST /api/v1/lulc/analyze/

Submit a new LULC analysis job.

Request
{
  "lat": 28.6139,
  "lon": 77.2090,
  "size_m": 1000,
  "start_year": 2020,
  "end_year": 2025
}
Parameter Type Description
lat number Latitude (-90 to 90). Processed at 6 decimal places.
lon number Longitude (-180 to 180). Processed at 6 decimal places.
size_m integer AOI size in meters (100-10000, default: 1000)
start_year integer Start year (min: 2016, default: 2020)
end_year integer End year (max: 2025, default: 2025)
Response (202 Accepted)
{
  "job_id": "lulc_a1b2c3d4e5f6",
  "status": "PENDING",
  "message": "Job queued for processing"
}
GET /api/v1/lulc/jobs/{job_id}/

Get the status of an LULC analysis job.

Response (200 OK)
{
  "job_id": "lulc_a1b2c3d4e5f6",
  "status": "RUNNING",
  "progress": {
    "years_completed": 3,
    "years_total": 6
  }
}
GET /api/v1/lulc/results/{job_id}/

Get the full results of a completed LULC analysis including satellite imagery URLs, land cover classification maps, and statistics.

POST /api/v1/lulc/batch/analyze/

Submit a batch of locations for LULC analysis (max 100 locations).

Request
{
  "locations": [
    {"lat": 28.6139, "lon": 77.2090, "label": "Delhi"},
    {"lat": 19.0760, "lon": 72.8777, "label": "Mumbai"}
  ],
  "size_m": 1000,
  "start_year": 2022,
  "end_year": 2024
}
GET /api/v1/lulc/batch/{batch_id}/

Get batch status and progress.

GET /api/v1/lulc/batch/{batch_id}/results/

Get paginated LULC results.

Land Cover Classes

Water
Trees
Grass
Crops
Shrub
Built Area
Bare Ground
Snow & Ice
Flooded Veg

Need help? Contact us at support@continuuiti.com

Climate Risk API

Physical climate hazard assessment

Overview

The Climate Risk API provides forward-looking climate hazard assessments based on CMIP6 climate model data. It evaluates 12 distinct climate hazards across multiple SSP scenarios and time horizons (baseline, 2030, 2040, 2050). Processing is asynchronous - you submit a job, then poll for results.

Climate Data

NASA NEX-GDDP-CMIP6

Water Stress

WRI Aqueduct 4.0

Endpoints

POST /api/v1/climate-risk/analyze/

Submit a new climate risk assessment job.

Request
{
  "lat": 28.6139,
  "lon": 77.2090,
  "scenarios": ["ssp245", "ssp585"],
  "horizons": ["baseline", "2030", "2050"]
}
Parameter Type Description
lat number Latitude (-90 to 90). Processed at 6 decimal places.
lon number Longitude (-180 to 180). Processed at 6 decimal places.
scenarios array SSP scenarios: ssp245, ssp585
horizons array Time horizons: baseline, 2030, 2040, 2050
Response (202 Accepted)
{
  "job_id": "climate_a1b2c3d4e5f6",
  "status": "PENDING",
  "message": "Climate risk assessment queued for processing"
}
GET /api/v1/climate-risk/status/{job_id}/

Get the status of a climate risk assessment job.

Response (200 OK)
{
  "job_id": "climate_a1b2c3d4e5f6",
  "status": "RUNNING",
  "progress": {
    "hazards_completed": 7,
    "hazards_total": 12,
    "current_hazard": "severe_storm"
  }
}
GET /api/v1/climate-risk/results/{job_id}/

Get the full results of a completed climate risk assessment including composite scores, hazard ratings, location context, and water stress indicators.

Hazard Types

Temperature

Heat wave, Cold stress, Temperature change

Precipitation

Drought, Extreme rainfall, Precipitation change

Compound

Severe storm, Wildfire, Landslide

Hydrological

River flood, Sea level rise, Water stress

Risk Levels

1 = Low 2 = Moderate 3 = High 4 = Severe 5 = Extreme

Climate Scenarios (SSPs)

  • SSP2-4.5: Middle-of-road scenario with moderate mitigation efforts (~2.7C warming by 2100)
  • SSP5-8.5: High emissions scenario with fossil fuel development (~4.4C warming by 2100)

Need help? Contact us at support@continuuiti.com

Damage Estimation API

HAZUS & JRC flood damage curves

Overview

The Damage Estimation API computes building-level flood damage estimates using two independent, peer-reviewed depth-damage function datasets. Processing is synchronous — results are returned immediately. Both single-building and batch (up to 5,000 buildings) endpoints are available.

US Curves

FEMA HAZUS 4.0

Global Curves

JRC Huizinga et al. 2017

Endpoints

POST /api/v1/damage/estimate/

Compute flood damage for a single building. Both HAZUS and JRC are computed independently.

Request
{
  "depth_ft": 5.0,
  "occupancy": "RES1",
  "stories_int": "2",
  "basement": false,
  "flood_zone": "riverine",
  "replacement_value": 350000,
  "country_iso": "USA",
  "floor_area_m2": 150,
  "label": "Single Family Home"
}

Common Parameters (required)

Parameter Type Description
depth_ft float Flood depth above grade (0–30 ft)
occupancy string HAZUS occupancy code (33 types)
label string Optional building label

HAZUS Parameters (all 4 required together, or omit all)

Parameter Type Description
stories_int string Story group (varies by occupancy)
basement boolean Whether building has a basement
flood_zone string riverine, coastal_a, or coastal_v
replacement_value float Building replacement cost
content_value float Optional. Auto-computed if omitted
first_floor_height_ft float Optional. Auto-computed if omitted

JRC Parameters (both required together, or omit both)

Parameter Type Description
country_iso string ISO 3166-1 alpha-3 code (e.g., USA, DEU)
floor_area_m2 float Building floor area in m²
Response (200 OK)
{
  "status": "COMPLETED",
  "hazus": {
    "damage_ratio": 0.20,
    "contents_ratio": 0.28,
    "structural_loss": 70000.00,
    "contents_loss": 49000.00,
    "total_loss": 119000.00,
    "depth_in_structure_ft": 4.0,
    "first_floor_height_ft": 1.0,
    "clamped": false
  },
  "jrc": {
    "damage_ratio": 0.6265,
    "total_loss_eur": 77901.57,
    "std_dev": 0.1503,
    "sector": "residential",
    "continent": "north_america",
    "depth_m": 1.2192,
    "fallback_used": false
  }
}

Response Status Values

  • COMPLETED — Both HAZUS and JRC returned results
  • PARTIAL — One source succeeded, the other failed (failed source is null)
  • FAILED — Both sources failed
POST /api/v1/damage/batch/estimate/

Estimate damage for up to 5,000 buildings in a single request.

Request
{
  "buildings": [
    {
      "depth_ft": 3.0, "occupancy": "RES1",
      "stories_int": "1", "basement": false,
      "flood_zone": "riverine", "replacement_value": 200000,
      "country_iso": "USA", "floor_area_m2": 100,
      "label": "Building A"
    },
    {
      "depth_ft": 5.0, "occupancy": "COM4",
      "stories_int": "<4", "basement": false,
      "flood_zone": "riverine", "replacement_value": 500000,
      "country_iso": "DEU", "floor_area_m2": 300,
      "label": "Building B"
    }
  ]
}
Response (200 OK)
{
  "total_count": 2,
  "succeeded": 2,
  "failed": 0,
  "results": [
    {
      "index": 0,
      "label": "Building A",
      "status": "COMPLETED",
      "result": { "hazus": { ... }, "jrc": { ... } }
    },
    {
      "index": 1,
      "label": "Building B",
      "status": "COMPLETED",
      "result": { "hazus": { ... }, "jrc": { ... } }
    }
  ]
}

Limit: Maximum 5,000 buildings per request. Each building uses the same field schema as the single /estimate/ endpoint.

GET /api/v1/damage/occupancy-types/

List all 33 HAZUS occupancy types with category and description.

Response (200 OK)
{
  "occupancy_types": [
    {"code": "RES1", "category": "Single Family", "description": "Single Family Dwelling"},
    {"code": "COM4", "category": "Professional/Technical", "description": "Professional/Technical Services"}
  ],
  "total_count": 33
}
GET /api/v1/damage/occupancy-types/{code}/

Get detail for one occupancy type, including valid story groups, basement options, and flood zones.

Response (200 OK)
{
  "code": "RES1",
  "category": "Single Family",
  "description": "Single Family Dwelling",
  "stories_options": [
    {"value": "1", "label": "1 Story"},
    {"value": "2", "label": "2 Story"},
    {"value": ">2", "label": "3+ Story"},
    {"value": "99", "label": "Split Level"}
  ],
  "basement_options": [true, false],
  "flood_zones_available": ["coastal_a", "coastal_v", "riverine"]
}
GET /api/v1/damage/countries/

List JRC countries with available damage data. Optional ?search= query param for filtering.

Response (200 OK)
{
  "countries": [
    {
      "iso_a3": "USA",
      "country_name": "United States",
      "sectors_available": ["residential", "commercial", "industrial", "agriculture"]
    },
    {
      "iso_a3": "DEU",
      "country_name": "Germany",
      "sectors_available": ["residential", "commercial", "industrial"]
    }
  ],
  "total_count": 196
}
GET /api/v1/damage/curves/hazus/

Get the raw HAZUS depth-damage curve (29 data points, −4 to +24 ft) for chart visualization.

Parameter Type Description
occupancy string HAZUS occupancy code
stories_int string Story group (URL-encode < and >)
basement string true or false
flood_zone string riverine, coastal_a, or coastal_v
Response (200 OK)
{
  "curve_id": "R12N",
  "occupancy": "RES1",
  "depth_points_ft": [-4, -3, -2, ..., 23, 24],
  "building_damage_pct": [0, 0, 0, ..., 63, 63],
  "content_damage_pct": [0, 0, 0, ..., 73, 73],
  "building_source": "FIA",
  "default_first_floor_height_ft": 1.0
}
GET /api/v1/damage/curves/jrc/

Get the raw JRC depth-damage curve (9 data points, 0–6 m) for chart visualization.

Parameter Type Description
sector string residential, commercial, industrial, agriculture, transport, infrastructure
country_iso string ISO A3 code. Derives continent. Takes priority over continent param.
continent string Alternative to country_iso: europe, north_america, asia, etc.
Response (200 OK)
{
  "sector": "residential",
  "continent": "north_america",
  "country_iso": "USA",
  "fallback_used": false,
  "depth_points_m": [0, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0],
  "damage_ratios": [0.20, 0.44, 0.58, 0.68, 0.78, 0.85, 0.92, 0.96, 1.0],
  "std_dev": [0.17, 0.14, 0.14, 0.17, 0.14, 0.13, 0.10, 0.06, 0.0],
  "max_damage": {
    "structure_per_m2": 552.65,
    "content_per_m2": 276.32,
    "total_per_m2": 828.97,
    "currency": "EUR_2010"
  }
}

Occupancy Categories

Residential (12)

RES1–RES6: Single family, multi-family, mobile home, hotel, dormitory, nursing home

Commercial (10)

COM1–COM10: Retail, wholesale, office, bank, hospital, clinic, entertainment, parking

Industrial (6)

IND1–IND6: Heavy, light, food/drugs, metals, high-tech, construction

Other (5)

AGR1, REL1, GOV1–2, EDU1–2: Agriculture, religious, government, education

HAZUS vs JRC

  • HAZUS: US-focused, 33 building types, separate structural + contents curves, 196 curves, monetary loss in input currency
  • JRC: Global (214 countries), 6 sectors, combined damage ratio, monetary loss in EUR 2010

Both are returned independently in every response and are not directly comparable.

Need help? Contact us at support@continuuiti.com

Flood Depth API retired

Retired 2026-10-21. Existing jobs, results, batches and exports stay readable.

This module is retired

The scenario-adjusted depth projection (a baseline depth scaled by a ratio of future to historical values) has been withdrawn: a deeper flood spreads into neighbouring cells, which a ratio never computes. New riverine and coastal work runs in the Riverine & Coastal API (/api/v1/flood-field/), which returns the two published depth fields over a 6 km box at native resolution, four return periods, present-day values, with per-band audits and no projection of any kind.

What still answers

Method Path Now
POST/api/v1/flood-depth/analyze/410 Gone with {"error": "retired", "replacement": "/api/v1/flood-field/"}
POST/api/v1/flood-depth/batch/analyze/410 Gone, same body
GET/api/v1/flood-depth/jobs/{job_id}/Job status of an existing job
GET/api/v1/flood-depth/results/{job_id}/Results of an existing job (200 when COMPLETED, 409 otherwise)
GET/api/v1/flood-depth/batch/{batch_id}/Batch status of an existing batch
GET/api/v1/flood-depth/batch/{batch_id}/results/Per-location results, paginated (page_size default 100, max 200)
GET/api/v1/exports/flood-depth/reports/Your reports
GET/api/v1/exports/flood-depth/batches/Your batches

Status values on existing records

JobsPENDING, PROCESSING, COMPLETED, FAILED
BatchesPROCESSING, COMPLETED, PARTIAL, FAILED

Results of existing reports keep their original shape: riverine and coastal depths per return period under the scenarios and horizons they were produced with, plus their quality flags. Read them as a historical record of the retired method, not as current guidance.

Questions about an old report? Email support@continuuiti.com.

CDEM API

Terrain, building footprints and road centrelines for one coordinate

One coordinate resolves into a site bundle: a bare-earth elevation grid, building footprints and road centrelines over a square box centred on the point. CDEM computes nothing — no ratings, no scores, no hydraulics. It emits data.

The response never carries the bundle

A bundle is roughly 0.9–2.2 MB. It is written to object storage and the API returns a ~1.8 KB summary plus a public bundle_url. Fetch the bundle from that URL directly — it needs no API key.

Bundles created before 2026-10-17 are stored gzipped under the CDN's own transport encoding, so a browser that calls .json() on one of those will throw; bundles created since are plain JSON. Until the last old bundle expires (180 days, so by mid-April 2027), check the first two bytes for 1f 8b and decompress before parsing; plain JSON passes straight through.

Endpoints

Method Path Purpose
POST/api/v1/cdem/analyze/Submit one site (202; 200 for a dry run)
GET/api/v1/cdem/jobs/{job_id}/Job status, per-layer progress and current_step
GET/api/v1/cdem/results/{job_id}/Summary + bundle_url — 200 for COMPLETED and PARTIAL, 409 while running
POST/api/v1/cdem/batch/analyze/Submit up to 10 sites
GET/api/v1/cdem/batch/{batch_id}/Batch status: progress.completed, progress.partial, progress.failed, progress.usable
GET/api/v1/cdem/batch/{batch_id}/results/Paginated per-site summaries
GET/api/v1/exports/cdem/reports/Your site bundles
GET/api/v1/exports/cdem/batches/Your batches

Submit a site

curl -X POST https://api.continuuiti.com/api/v1/cdem/analyze/ \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"lat": 17.4245, "lon": 78.3804, "half_km": 1.0, "label": "Site A"}'
Field Required Notes
latyesWGS84, −90 to 90
lonyesWGS84, −180 to 180
half_kmnoHalf-width in km. Default 1.0 (a 2 km box), maximum 3.0
labelnoFree text
dry_runnoFree sandbox run. Returns 200 with the mock bundle inline — dry bundles are never written to storage

Async only. A bundle takes roughly 30 seconds to 3 minutes; most of that is queueing. Poll /jobs/{job_id}/ until terminal, then fetch /results/{job_id}/. Jobs also complete unattended — you can submit and come back later.

Job status

PENDING / QUEUED / PROCESSINGIn flight. progress is an object keyed by layer and is empty while queued; current_step names the layer being worked and is null until a worker picks the job up.
COMPLETEDEvery layer is ok or confirmed-empty.
PARTIALA success. Terrain is present and at least one vector layer is not. It carries a usable bundle_url and is terminal — do not treat it as a failure.
FAILEDTerrain unavailable, so there is no bundle.

Layer status — read before consuming a layer

Each of the three layers carries its own status, and three of the four are not "ok". An empty building layer and a failed building layer are the same empty array and mean opposite things — one is farmland, the other a dense district you would otherwise model as bare earth.

okFetched and complete.
empty_confirmedThe source genuinely holds nothing here. The emptiness is real.
unavailableThe source does not cover this location. Retrying will not help.
failedDo not read as empty. We could not fetch it; retry later.

Geometry conventions

  • Cells are rectangular and increasingly so with latitude. Read dx_m and dy_m separately; assuming square cells skews the site.
  • origin is the centre of the north-west cell, not a box corner. row_order is north-to-south.
  • Elevations are metres above EGM2008, bare earth. Buildings are not stamped in.
  • NoData is null, never a sentinel — a −9999 would read as a very deep pit.
  • Buildings and roads may extend beyond the terrain box: footprints overscan by 50 m and roads keep whole segments.

Batch

curl -X POST https://api.continuuiti.com/api/v1/cdem/batch/analyze/ \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"locations": [{"lat": 17.42, "lon": 78.38, "label": "A"}], "half_km": 1.0}'

Maximum 10 sites per batch, for real and sandbox runs alike. Each site is a separate bundle and 30 seconds to 3 minutes of work, so a batch is a handful of sites rather than a portfolio sweep. half_km is batch-level and applies to every site.

The submit path is /cdem/batch/analyze/, the same shape as every other batch module. A batch status payload counts PARTIAL sites separately under progress.partial (progress.usable = completed + partial).

Retention

Bundles are retained for 180 days, then deleted. The summary is kept indefinitely, so an expired report still tells you what was there. Re-running the same coordinate rebuilds the bundle.

Licensing

Licences travel per layer, not per bundle. Terrain (CC BY 4.0) and buildings (CC BY 4.0 or CDLA Permissive 2.0) are attribution-only. Roads are ODbL 1.0, which is share-alike on derived databases: redistributing a derivative of a road-bearing bundle carries that obligation. Attribution strings are in the payload; please surface them.

Questions about CDEM? Email support@continuuiti.com.

Riverine & Coastal API

The published riverine and coastal flood depth fields over a 6 km box, for one coordinate

One coordinate resolves into two present-day hazard grids over a 6 km box: the JRC GloFAS riverine depth field at its native ~93 m and the WRI Aqueduct coastal inundation field at its native ~928 m, each for the 1 in 10, 50, 100 and 500 year return periods. Values are raw and unmasked, with a per-band audit of what is masked, exactly zero, the source's fill value or a real depth. The service computes nothing: no ratio, no scenario, no horizon, no flags, no projection of any kind.

The response never carries the bundle

The band arrays (about 200 KB) are written to object storage as plain JSON and the API returns a few-KB summary plus a public bundle_url and expires_at. Fetch the bundle from that URL directly; it needs no API key and parses with a plain .json().

Endpoints

Method Path Purpose
POST/api/v1/flood-field/analyze/Submit one site (202; 200 for a dry run)
GET/api/v1/flood-field/jobs/{job_id}/Job status, per-layer progress, current_step, expires_at
GET/api/v1/flood-field/results/{job_id}/Summary + bundle_url + expires_at: 200 for COMPLETED and PARTIAL, 409 while running
POST/api/v1/flood-field/batch/analyze/Submit up to 100 sites
GET/api/v1/flood-field/batch/{batch_id}/Batch status: progress.completed, progress.partial, progress.failed, progress.usable
GET/api/v1/flood-field/batch/{batch_id}/results/Paginated per-site summaries
GET/api/v1/exports/flood-field/reports/Your sites
GET/api/v1/exports/flood-field/batches/Your batches

Submit a site

curl -X POST https://api.continuuiti.com/api/v1/flood-field/analyze/ \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"lat": 23.6220, "lon": 58.2498, "label": "Muscat coastal site A"}'
Field Required Notes
latyesWGS84, −90 to 90
lonyesWGS84, −180 to 180
labelnoFree text, the only human-readable handle a report has
half_kmnoHalf-width in km. Default 3.0 (a 6 km box, as every engagement), maximum 3.0
dry_runnoFree sandbox run. Returns 200 with a mock bundle inline under bundle; dry bundles are never written to storage. Mock geometry sits on the real graticule, so georeferencing is testable

Async only. A site takes seconds to tens of seconds (two Earth Engine reads). Poll /jobs/{job_id}/ until terminal, then fetch /results/{job_id}/. Jobs also complete unattended.

Job status

PENDING / QUEUED / PROCESSINGIn flight. progress is an object keyed by layer (riverine, coastal) and is empty while queued; current_step names the layer being read and is null until a worker picks the job up.
COMPLETEDBoth layers are ok or confirmed-empty.
PARTIALA success. One layer was read and the other is unavailable or failed. It carries a usable bundle_url with the good layer and is terminal; do not treat it as a failure.
FAILEDNeither layer could be read, or the bundle could not be stored. error.code is SOURCE_UNAVAILABLE (final; no retry can help), SOURCE_TIMEOUT, SOURCE_FAILED or UNEXPECTED_ERROR (retried upstream with a cooldown).

Layer status

Each of the two layers carries its own status. An empty grid and a failed read are different things: an inland box where the coastal source holds nothing is a real reading, a read error is not a reading at all.

okRead in full. A riverine layer where every non-null cell is the fill value is still ok, with real_cells 0.
empty_confirmedThe source was read in full and holds nothing in this box (every cell masked). The job is still COMPLETED.
unavailableThe source does not cover this location. Retrying will not help.
failedDo not read as empty. We could not read it; retry later.

Geometry and value conventions

  • Each layer is sampled in its own native grid (EPSG:4326). row_order is north-to-south; origin is the centre of the north-west cell.
  • dx_deg and dy_deg are carried so you can georeference without recovering them from the rounded metre sizes or the request box.
  • pin (row, col, idx) and site_cell per return period are in the summary, so a list page needs no bundle fetch.
  • Riverine: null is "outside the modelled floodplain"; cells valued exactly 1.000 m are a tile fill value on permanent water, counted in exact_1p000_cells and excluded from real_cells and real_max, never masked. valid_cells + masked_cells + outside_footprint_cells equals the cell count.
  • Coastal: the sea is null, dry land is a real 0.0. exact_zero_cells is a first-class number; a 0.0 maximum is a value. Never test a depth for truthiness.
  • Band arrays are flat, row-major, width × height long, with null for masked cells. Audit maxima are rounded (3 decimals riverine, 4 coastal); the bands are the raw source values.

Batch

curl -X POST https://api.continuuiti.com/api/v1/flood-field/batch/analyze/ \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"locations": [{"lat": 23.62, "lon": 58.25, "label": "A"}], "half_km": 3.0}'

Maximum 100 sites per batch, for real and sandbox runs alike. An optional half_km in the request body applies to every site (Tools stamps it on each item upstream; the default 3.0 is used when absent). A batch status payload counts PARTIAL sites separately under progress.partial (progress.usable = completed + partial). Batch results are paginated: page_size defaults to 100 and is capped at 200.

Retention

Bundles are retained for 180 days, then deleted; the job status and the results body carry expires_at. The summary is kept indefinitely, so an expired report still tells you what was there. Re-running the same coordinate reads the fields again.

Licensing

Licences and attribution travel per layer in the payload. The JRC datasets are available without restriction on use or distribution (Baugh et al. 2024, European Commission Joint Research Centre). WRI Aqueduct Flood Hazard Maps V2 are CC BY 4.0 (World Resources Institute). Please surface the attribution strings.

Questions about the flood fields? Email support@continuuiti.com.