Skip to content

HTTP API

All commands are HTTP POST requests to port 8080 under /send/…. Status is read through HTTP GET endpoints and the TCP telemetry stream.

Two computers can drive the same drone over HTTP. Which one is in command is decided purely by the X-Safety-Token header on each request:

RequestClassified as
carries the valid X-Safety-TokenSafety Computer
anything else (no header, wrong token)Pilot Computer

Two-Computer Safety Control — request flow

How a single HTTP command is arbitrated: the X-Safety-Token header classifies the request, ControlAuthority holds one in-memory latch, and the first Safety command seizes control and cancels whatever the Pilot was flying.

Rules enforced by the app on every /send/* command:

  • The Pilot Computer holds control at startup and flies the mission normally.
  • The first command from the Safety Computer latches authority to SAFETY, cancels whatever autonomous loop the Pilot left running, and holds the aircraft in place.
  • From then on every Pilot command is rejected with REJECTED: Safety Computer is in control. Pilot commands are blocked.
  • The takeover is persistent — there is no timeout. If the Safety Computer goes silent, the Pilot does not regain control.
  • The only way back is POST /releaseSafetyControl, which only the Safety Computer may call.
  • An app restart resets to Pilot control (“restart == fresh mission”). State is in-memory only.

While the Safety Computer holds authority, a red SAFETY COMPUTER IN CONTROL banner is shown over the video feed. Normal Pilot control shows no banner.

This axis is independent of the RC manual-override latch: that one tracks the physical pilot on the sticks, this one tracks which computer commands the server.

from lyrebird_groundstation.safety import DJIInterfaceSafety
safety = DJIInterfaceSafety("192.168.1.100") # every command carries the token
safety.requestSendGotoAltitude(30.0) # first command seizes control
safety.requestReleaseSafetyControl() # hand authority back to the Pilot
Method & EndpointBodyDescription
POST/releaseSafetyControlReturn authority to the Pilot Computer (Safety Computer only)

Control Endpoints (HTTP POST — Port 8080)

Section titled “Control Endpoints (HTTP POST — Port 8080)”
Method & EndpointBodyDescription
POST/send/takeoffTakeoff
POST/send/landLand
POST/send/RTHReturn to home (aborts active mission + disables VS first)
POST/send/enableVirtualStickEnable Virtual Stick mode
POST/send/abortMissionStop mission + disable Virtual Stick
POST/send/abortAllStop all active missions (DJI native + Virtual Stick)
POST/send/abort/DJIMissionStop DJI native mission only
POST/send/stickleftX,leftY,rightX,rightYDirect AVS velocity input (values ∈ [-1, 1])
POST/send/gotoWaypointNoseForwardlat,lon,alt,yaw[,speed]Turn to face the leg, fly forward, rotate to yaw on arrival (yaw = final heading)
POST/send/gotoWaypointHoldHeadinglat,lon,alt,yaw[,speed]Hold yaw for the whole flight (drone crabs sideways), tighter arrival tolerance
POST/send/navigateTrajectoryDJINativespeed;lat,lon,alt;…DJI native KMZ mission (≥ 2 waypoints)
POST/send/gotoYawyaw_degreesRotate to heading
POST/send/gimbal/rel_pitchroll,pitch,yawGimbal pitch relative to current angle (degrees)
POST/send/gimbal/rel_yawroll,pitch,yawGimbal yaw relative to current angle (degrees)
POST/send/captureThermalImageCapture on the thermal lens. Returns a JSON capture descriptor
POST/send/captureTemperatureRead the thermal max temperature. Returns {"thermalMaxTemp": <float or null>}
POST/send/listMediaList every file on the SD card as JSON
POST/send/downloadMediaByName<fileName>Download one media file by name; responds with the raw file bytes
POST/send/lrf/measureFire the laser rangefinder. Returns distance, geo-referenced target, and laser state as JSON. distance and target are non-null only when the laser locks (state NORMAL, needs a GPS fix)
POST/send/dropRelease the payload on airframes with a drop port configured in the active profile; rejected otherwise
POST/send/gotoAltitudealtitude_mChange altitude
POST/send/gimbal/pitchroll,pitch,yawSet gimbal pitch
POST/send/gimbal/yawroll,pitch,yawSet gimbal yaw joint angle
POST/send/camera/zoomzoom_ratioSet camera zoom
POST/send/camera/startRecordingStart recording
POST/send/camera/stopRecordingStop recording
POST/send/setRTHAltitudealtitude_mSet RTH altitude
POST/send/deactivateManualOverrideRe-enable autonomous commands after pilot override
POST/send/autoSensing/startEnable DJI AutoSensing object detection where supported
POST/send/autoSensing/stopDisable DJI AutoSensing object detection
Method & EndpointReturnsDescription
GET/configJSONDrone name, IP, HTTP/telemetry ports, and current video mode
GET/get/isManualOverrideActiveJSON/textManual override state
GET/get/autoSensing/statusJSONAI detection status and target count
GET/get/autoSensing/targetsJSONCurrent detected targets with bounding boxes

All other flight state data is available via the TCP telemetry stream on port 8081. Use GET /config for connection metadata and auto-discovery.