Zequent Client SDK — Connector
client.connector() gives your application direct access to the platform's system of record: asset lookups, organization info, scheduler management, technical configuration, operational policies, and asset payloads. Most integrations only need a handful of these — asset lookup and scheduler management are the most common.
Full method-by-method reference: Connector API Reference.
For Python, see CONNECTOR_PYTHON.md.
Requests share a context
Every Connector request carries an optional ConnectorRequestContext for transaction correlation — you don't need to fill it in for normal use; the SDK generates a transaction ID automatically if you leave it unset.
import com.zqnt.sdk.client.connector.domains.*;
var request = GetAssetBySnRequest.builder()
.context(ConnectorRequestContext.builder().sn("YOUR_DEVICE_SN").build())
.build();
client.connector().getAssetBySn(request)
.thenAccept(response -> System.out.println("Asset: " + response));
Looking up an asset
var request = GetAssetByIdRequest.builder()
.assetId("550e8400-e29b-41d4-a716-446655440000")
.build();
client.connector().getAssetById(request)
.thenAccept(response -> System.out.println(response));
Asset payload storage (arbitrary versioned metadata — flight-plan artifacts, calibration data), organization lookup, and scheduler CRUD follow the same request/response shape — see the reference for the full method list.
Missions and tasks are records, not flights
These methods create and read mission/task records. Creating one does not fly anything by itself. How a flight is actually triggered depends on the adapter — see Waypoint Missions.
For real use, create missions and waypoint tasks through
client.missionAutonomy()instead — confirmed against the backend, itscreateMission/createTaskroute-optimize (and, for a task, expand around the mission's no-fly zones) before writing the exact same record shown below. The example here still works — same record, no optimization — butmissionAutonomy()is what you want day to day. See the Mission Autonomy reference.
import com.zqnt.utils.missionautonomy.domains.MissionDTO;
import com.zqnt.utils.mission.proto.MissionType;
var mission = MissionDTO.builder()
.name("North Perimeter Patrol")
.type(MissionType.MISSION_TYPE_PERIMETER_PATROL)
.build();
var request = CreateMissionRequest.builder().mission(mission).build();
client.connector().createMission(request)
.thenAccept(response -> {
if (!response.isSuccess()) {
log.warn("Create mission failed: {}", response.getError().getErrorMessage());
return;
}
System.out.println("Mission created: " + response.getMissionId());
});
No-fly zones
A mission's no-fly zones (NFZ) tell the platform's route planner where it must route drones — and dock-return paths — around. A zone's area can be a polygon, bounding box, circle, or raw GeoJSON, controlled by GeoAreaDTO.type (full requirements per type in the reference):
import com.zqnt.utils.missionautonomy.domains.*;
import com.zqnt.utils.mission.proto.GeoAreaType;
import com.zqnt.utils.mission.proto.MissionZoneType;
import com.zqnt.utils.mission.proto.ZoneEnforcementType;
var zone = MissionZoneDTO.builder()
.name("Substation exclusion")
.type(MissionZoneType.MISSION_ZONE_TYPE_NO_FLY)
.enforcementType(ZoneEnforcementType.ZONE_ENFORCEMENT_TYPE_HARD_BLOCK)
.area(GeoAreaDTO.builder()
.type(GeoAreaType.GEO_AREA_TYPE_CIRCLE)
.center(GeoPointDTO.builder().latitude(52.520008).longitude(13.404954).build())
.radiusMeters(150.0)
.build())
.active(true)
.build();
var request = UploadMissionZonesRequest.builder()
.missionId(missionId)
.zones(List.of(zone))
.replaceExisting(false)
.build();
client.connector().uploadMissionNfzZones(request)
.thenAccept(response -> System.out.println("Zones uploaded: " + response.isSuccess()));
Correlating a task with an external flight record
var request = GetTaskByFlightIdRequest.builder()
.flightId("FLIGHT-20260901-0001")
.build();
client.connector().getTaskByFlightId(request)
.thenAccept(response -> System.out.println("Task: " + response.getTaskId()));
getTaskByFlightId looks up a task by the external flight ID an edge adapter assigned it (TaskDTO.externalTaskId) — useful for correlating a vendor-side flight record back to its Zequent task without knowing the platform's task ID up front.
Beta preview — 2.0.x, not yet released. Every Mission/Task method above becomes a
@Deprecatedstub that fails immediately on an unmerged branch. See the 2.0.x migration guide for what replaces them.
Checking what an asset supports
client.remoteControl().getCapabilities(sn)
.thenAccept(snapshot -> snapshot.getCapabilities()
.forEach(c -> System.out.println(c.getCommandId() + " -> " + c.getState())));
Each entry carries the command id, a description, its target type, and an input schema. Use it to build a UI that only shows commands the asset actually implements. What an asset reports comes from its edge adapter — see Edge SDK — Connector.
Error handling
Connector responses carry a hasErrors flag rather than throwing for expected business errors (not found, validation failure). Handle both:
client.connector().getAssetBySn(request)
.thenAccept(response -> {
if (response.getHasErrors()) {
log.warn("Asset lookup failed: {}", response.getError().getErrorMessage());
return;
}
// use response
})
.exceptionally(err -> {
log.error("Connector call failed", err);
return null;
});
See also
- Connector API Reference — every method, grouped by area
- Waypoint Missions — which adapter uses which execution path
- Functional Responses — what a response actually confirms