OpenDroneKit

API guide

The desktop Api and the HTTP service.

Updated 2026-10-02Mirrored from docs/API_GUIDE.md at 1ef6351 · Markdown

Two APIs, for two different things.

Which one you want

app.api.Apiservices.api (HTTP)
ShapePython object, one method per capabilityFastAPI application
UsersSingle, localMulti-user, organisations, roles
StateOne AppSessionPostgreSQL / SQLite
Use forDesktop shell, scripts, notebooksHub deployment, web client

The desktop Api is the reference surface: every capability in the feature registry is reachable through it. The HTTP service wraps a subset for multi-user deployment.

Desktop API

from app.api import Api
from app.session import AppSession
from app.store import ProjectStore

session = AppSession(store=ProjectStore("projects.db"))
session.create_project("site", root_dir="./site")
api = Api(session)

Every method returns a dict with an ok boolean. Failures carry error, not reason — a detail worth knowing before you write a handler against it:

result = api.plan_mission({"altitude_m": 60.0})
if not result["ok"]:
    print(result["error"])

Successful results may also carry warnings. A warning does not make the result invalid; it states what the result assumed. Ignoring warnings is how a flat-earth plan gets flown over a slope.

Representative methods:

api.set_aoi(polygon)
api.plan_mission(options)                 # options["mode"] selects the template
api.reconstruction_capabilities()         # what this machine can produce
api.check_spatial_reference(paths, gcp_count=0)
api.size_reconstruction_job(image_count=1200)
api.plan_job_chunks(image_count=5000)
api.find_ponding(dsm, vertical_accuracy_m=0.05)
api.compare_surveys(before, after)
api.build_asset_inventory(instances, model_key=..., model_sha256=..., crs="EPSG:32643")
api.asset_taxonomy("power")
api.demo_workflow()

HTTP API

uvicorn services.api.main:app --reload

Interactive documentation is generated at /docs, and it is the authority — the routes below are the shape, not a contract to code against blind.

AreaRouter
System/health, /health/live, /health/ready, /metrics
Auth/auth
Organisations/organizations
Projects, datasets, processingprojects, datasets, processing
Inspection, annotationsinspection, annotations
Sharing, fleet, resources, eventssharing, fleet, resources, events

Health endpoints are not interchangeable

  • /health/live — the process is up. Use for liveness.
  • /health/ready — dependencies (database, object store) are reachable. Use for readiness.

Pointing a readiness probe at the liveness endpoint sends traffic to a pod that cannot reach its database, and restarting that pod — which is what a failing liveness probe does — will not fix a database that is down.

What /health tells you about spatial storage

The health payload reports the database backend honestly:

{"backend": "postgresql", "postgis": true,
 "geometry_storage": "geojson_text", "native_geometry_columns": false}

postgis: true means the extension is available. It does not mean your geometry is natively indexed — every geometry column in the current schema is text holding GeoJSON, on both backends, and spatial filtering happens in Python. Size your workloads accordingly. This field used to report native_geometry whenever the extension answered, which was a claim about the server rather than about the schema.

Uploads

Dataset uploads are resumable, and upload paths are contained: a key that would escape the storage root is rejected rather than normalised. Do not rely on the client to sanitise paths — the server does not trust it either.

Webhooks and realtime

Webhooks carry a secret; only its prefix is ever returned after creation. Realtime updates are available for processing progress. Neither is required — the toolkit is offline-first, and nothing calls out unless you configure it to.

This page is the repository’s own docs/API_GUIDE.md, rendered at build time from commit 1ef6351. Links to code open on GitHub at the same commit.