Lenga Maps
LENGA MAPS

Unmasking Africa with Data and Intelligence

Back home

REST API · v1

Pull every Lenga Maps dataset
from one endpoint.

Stable JSON. Bearer auth. Presigned downloads from Cloudflare R2. Designed so a research script can grab continental coverage in a single call — no GUI, no manual hunt.

54 countries

Africa-wide coverage in every dataset where applicable.

Stable contracts

Versioned at /v1/. Breaking changes go to /v2/.

Reproducible

Same key, same script, same data — every nightly run.

Authentication

Generate a bearer token on the API keys page. Available exclusively on For Project Teams and Businesses (per-seat team plans — get a quote). Individual plans, including Max, don't carry API access. Send your key on every request:

Authorization: Bearer lm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are shown once at creation time. We store only a SHA-256 hash — if you lose your key, revoke it and mint a new one.

Quotas

  • · 5,000 requests / month per key
  • · 50 GB egress / month per key (counted as the size of every file we sign)
  • · Hard 429 on overage — email lengamaps@gmail.com for a higher cap
  • · Pre-signed URLs are valid for 1 hour

Endpoints

GET/api/v1/datasets

List every dataset and its file count.

curl https://lenga-maps.com/api/v1/datasets \
  -H "Authorization: Bearer lm_live_…"

Response (truncated):

{
  "datasets": [
    {
      "id":          "rivers",
      "name":        "River networks",
      "description": "HydroSHEDS / FAO river networks per African country.",
      "category":    "hydrology",
      "source":      "HydroSHEDS / FAO",
      "file_count":  54
    },
    { "id": "watersheds", "...": "..." }
  ],
  "quotas": {
    "requests_used":  12,
    "requests_limit": 5000,
    "egress_bytes_used":  4421160960,
    "egress_bytes_limit": 53687091200
  }
}
GET/api/v1/datasets/{id}

Full metadata for a dataset, plus the per-country file list (no presigned URLs).

curl "https://lenga-maps.com/api/v1/datasets/rivers?country=ZM" \
  -H "Authorization: Bearer lm_live_…"

Query params: country (optional) — ISO-3 code (ZM) or full name (Zambia).

GET/api/v1/datasets/{id}/download?country=ZM

Presigned download URL for ONE country's file. Valid for 1 hour.

curl "https://lenga-maps.com/api/v1/datasets/lulc/download?country=ZM" \
  -H "Authorization: Bearer lm_live_…"

Response:

{
  "file": {
    "country_iso3":        "ZMB",
    "country_name":        "Zambia",
    "r2_key":              "datasets/zambia/lulc/zmb_lulc_2021.tif",
    "file_size_mb":        118.4,
    "file_format":         "GeoTIFF",
    "source":              "ESA WorldCover 2021 v200",
    "download_url":        "https://…r2.cloudflarestorage.com/…?X-Amz-…",
    "download_expires_in": 3600
  }
}
GET/api/v1/datasets/{id}/bundle

Presigned URLs for EVERY country file in the dataset — continental coverage in one call.

curl "https://lenga-maps.com/api/v1/datasets/rivers/bundle" \
  -H "Authorization: Bearer lm_live_…"

Returns a JSON manifest of all files with presigned URLs. Stream them in parallel from your client — we don't serve a single ZIP because a 50 GB concatenation would burn through your quota and our memory budget. The official lenga-maps Python client does this transparently.

Quick Python example

import os, requests
from pathlib import Path

API = "https://lenga-maps.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['LENGA_API_KEY']}"}

# Pull all river networks for Africa in one shot
bundle = requests.get(f"{API}/datasets/rivers/bundle", headers=HEADERS).json()

out = Path("rivers")
out.mkdir(exist_ok=True)

for f in bundle["bundle"]["files"]:
    dst = out / f"{f['country_iso3']}.zip"
    print(f"→ {f['country_name']}  ({f['file_size_mb']:.1f} MB)")
    with requests.get(f["download_url"], stream=True) as r:
        r.raise_for_status()
        with dst.open("wb") as fh:
            for chunk in r.iter_content(1024 * 1024):
                fh.write(chunk)

Errors

StatuserrorWhen
401missing_api_key No Authorization header.
401invalid_api_key Key not recognised.
401revoked_api_key Key was revoked.
403plan_inactive Account isn't Business / plan expired.
404dataset_not_found Dataset id doesn't exist.
404file_not_found Country has no file in this dataset.
429quota_exceeded Monthly request or egress cap hit.

Need the API on a custom plan?

Higher quotas, dedicated support, on-prem mirror — talk to us.

or copy our email:lengamaps@gmail.com