Access:
org_type= Airspace Manager or Airspace Monitor, Member+. The caller’s organisation must hold a zone membership (Manager or Monitor) for the zone the flight operates within. Direct user-to-zone membership is not required. Results are filtered to zones the caller’s organisation can access. Alerts require Airspace Manager (Admin+) with org-level Manager zone membership. See Access control.
Airspace Awareness Endpoints Summary
| Endpoint | Method | Operation Name | Description |
|---|---|---|---|
/airspace/active-flights | GET | Get Active Flights | Get all active flights |
/airspace/active-flights/assets/\{asset_uuid\} | GET | Get One Active Flight | Get details of a specific active flight |
/airspace/assets/\{asset_uuid\} | GET | Get Asset Details | Get detailed asset information for awareness |
/airspace/assets/\{asset_uuid\}/plans | GET | Get Asset Flight Plans | Get all flight plans associated with an asset |
/airspace/assets/\{asset_uuid\}/plans/\{plan_uuid\} | GET | Get One Asset Flight Plan | Get details of a specific flight plan for an asset |
/airspace/assets/\{asset_uuid\}/alert | POST | Create Alert | Trigger or log a flight alert or incident |
/airspace/live/token | POST | Issue Monitoring Token | Single-use, short-lived token for the WebSocket below |
wss://…/v1/airspace/live | WS | Live Telemetry Fan-out | Subscribe by zone, asset, or visible map viewport |
Get Active Flights
GET /airspace/active-flights
Get all active flights.
Query Parameters:
| Param | Type | Description |
|---|---|---|
page | int (optional) | Page number (default: 1) |
limit | int (optional) | Records per page (default: 25) |
Responses:
- 200 OK:
{
"data": [
{
"session_uuid": "550e8400-e29b-41d4-a716-446655440010",
"asset_uuid": "e7a6d7a1-ffb2-4d62-bd7a-034fb8a34a55",
"asset_uin": "UIN-IND-01239X",
"model_name": "Switch",
"model_uuid": "f0154cf0-fef0-4c3e-b816-43e34b9cfbc1",
"pilot_udai_id": "UDAI-USR-401",
"pilot_uuid": "550e8400-e29b-41d4-a716-446655440000",
"plan_uuid": "c1d2e3f4-1234-4abc-9000-aabbccddeeff",
"mission_uuid": "a9f2aeb8-b0b2-4b9e-8d3b-61d4f37a742b", // Nullable
"height": 85,
"location": {
"coordinates": [
77.2090,
28.6139
],
"label": "New Delhi, India"
},
"status": "IN_FLIGHT"
}
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page": 1,
"per_page": 25,
"has_next": false,
"has_previous": false
}
}Get One Active Flight
GET /airspace/active-flights/assets/{asset_uuid}
Get details of a specific active flight.
Responses:
- 200 OK:
{
"data": {
...
}
}- 404 Not Found:
{
"error": "No active flight found for this asset"
}Get Asset Details
GET /airspace/assets/{asset_uuid}
Get detailed asset information for situational awareness.
Responses:
- 200 OK:
{
"data": {
"asset": {
"asset_uuid": "e7a6d7a1-ffb2-4d62-bd7a-034fb8a34a55",
"asset_udai_id": "UDAI-AST-005",
"asset_uin": "UIN-987654321",
"status": 1,
"org_owner_uuid": "550e8400-0000-41d4-a716-446655440000",
"memberships": [
{
"org_uuid": "550e8400-0000-41d4-a716-446655440000",
"org_udai_id": "UDAI-ORG-801",
"membership_type": 1
},
{
"org_uuid": "9f3a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"org_udai_id": "UDAI-ORG-102",
"membership_type": 2
}
],
"total_distance": 15200,
"total_endurance": 840,
"total_flights": 74
},
"model": {
"model_name": "Switch",
"model_variant": "v2.Pro",
"model_version": "v2.0",
"category": 2,
"sub_category": 2,
"class": 3,
"max_takeoff_weight": 12.5,
"max_endurance": 3.5,
"max_range": 15,
"max_speed": 60,
"max_height": 120,
"operation_envelope": "VLOS",
"frequency": "2.4GHz",
"application": "Border Surveillance"
}
}
}- 404 Not Found:
{
"error": "Asset not found"
}Get Asset Flight Plans
GET /airspace/assets/{asset_uuid}/plans
Get all flight plans associated with an asset.
Query Parameters:
| Param | Type | Description |
|---|---|---|
page | int (optional) | Page number (default: 1) |
limit | int (optional) | Records per page (default: 25) |
Responses:
- 200 OK:
{
"data": [
{
"plan_uuid": "c1d2e3f4-1234-4abc-9000-aabbccddeeff",
"plan_udai_id": "UDAI-PLN-0001",
"mission_uuid": "a9f2aeb8-b0b2-4b9e-8d3b-61d4f37a742b",
"org_uuid": "550e8400-0000-41d4-a716-446655440000",
"asset_uuid": "e7a6d7a1-ffb2-4d62-bd7a-034fb8a34a55",
"user_uuid": "550e8400-e29b-41d4-a716-446655440000",
"payload_uuid": "f8e9d0c1-b2a3-4455-6677-889900aabbcc",
"schedule_start_time": "2025-07-05T08:00:00Z",
"schedule_end_time": "2025-07-05T09:30:00Z",
"2d_flight_envelope": {
"type": "Polygon",
"coordinates": [
[
[
77.123,
28.567
],
[
77.124,
28.567
],
[
77.124,
28.566
],
[
77.123,
28.566
],
[
77.123,
28.567
]
]
]
},
"min_height": 40,
"max_height": 120,
"airspace_restrictions_covered": [
"ZONE-RESTRICTED-007"
],
"permission_status": "APPROVED",
"flight_status": "SCHEDULED",
"created_at": "2025-07-04T18:30:00Z",
"updated_at": "2025-07-04T19:00:00Z"
}
],
"pagination": {
"total_records": 1,
"total_pages": 1,
"current_page": 1,
"per_page": 25,
"has_next": false,
"has_previous": false
}
}- 404 Not Found:
{
"error": "Asset not found"
}Get One Asset Flight Plan
GET /airspace/assets/{asset_uuid}/plans/{plan_uuid}
Get details of a specific flight plan for an asset.
Responses:
- 200 OK:
{
"data": {
...
}
}- 404 Not Found:
{
"error": "Asset or flight plan not found"
}- 410 Gone:
{
"error": "Flight plan has been deactivated"
}Create Alert
POST /airspace/assets/{asset_uuid}/alert
Trigger or log a flight alert or incident for review or notification.
Request Body:
{
"session_uuid": "string (UUID)",
"asset_uuid": "string (UUID)",
"alert_type": "zone_violation | altitude_breach | geofence_exit",
"message": "string",
"triggered_by": "string (user_uuid)"
}Responses:
- 200 OK:
{
"message": "Alert submitted successfully",
"status": "logged"
}- 400 Bad Request:
{
"error": "'alert_type' must be one of: zone_violation, altitude_breach, geofence_exit"
}- 404 Not Found:
{
"error": "Asset or flight session not found"
}- 422 Unprocessable Entity:
{
"error": "'session_uuid' is required"
}POST /airspace/live/token
Issues a single-use, short-lived token for opening the live telemetry WebSocket below, so a browser never has to put its session JWT in a URL.
Responses:
- 200 OK:
{
"token": "9f2c1a7e...",
"expires_in_seconds": 30
}Live Telemetry Subscription WebSocket
Access:
org_type= Airspace Manager, Airspace Monitor, Asset Owner, or Asset Manufacturer. Specific access rules apply per subscription type. Zone subscriptions are resolved through organisation memberships, not direct user-to-zone mappings.
WS wss://api.udai.live/v1/airspace/live?token={value}Call POST /airspace/live/token first and pass the returned token as the query value; it works once and expires in seconds. After connecting, the server sends a connection_ack listing the actions available to that user. Clients then send zone, asset, or viewport subscription messages over this same WebSocket to receive live telemetry frames.
Connection acknowledgement (server → client on connect):
{
"type": "connection_ack",
"connectionId": "f9a37388-3f76-4b01-8290-71c7bbab1d01",
"userUuid": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2026-06-16T07:32:10Z",
"availableActions": [
"subscribe",
"unsubscribe",
"subscribe_asset",
"unsubscribe_asset",
"set_bounds",
"clear_bounds"
]
}set_bounds and clear_bounds are included only for an active Member, Admin, or Owner of an active Airspace Manager organisation. Other actions are also subject to the access rules of their subscription type.
Zone Subscription
Subscribe to all live frames from any asset operating inside a specific airspace zone.
Access:
org_type= Airspace Manager or Airspace Monitor. The caller must be an active Member+ of an organisation that holds an active Manager or Monitor membership for the target zone. Direct user-to-zone memberships are not used for live telemetry authorisation.
Client → server (subscribe):
{
"action": "subscribe",
"zoneUuid": "4f39caae-2a73-426e-bb0c-239e25a01a14",
"mode": "full"
}| Field | Type | Description |
|---|---|---|
action | string | "subscribe" |
zoneUuid | UUID | Zone to monitor |
mode | string | "full" (all fields) or "alerts" (alert events only) |
Server → client (response):
{
"type": "subscription_response",
"zoneUuid": "4f39caae-2a73-426e-bb0c-239e25a01a14",
"mode": "full",
"message": "Successfully subscribed to zone"
}Client → server (unsubscribe):
{
"action": "unsubscribe",
"zoneUuid": "4f39caae-2a73-426e-bb0c-239e25a01a14"
}Asset Subscription
Subscribe to live frames for a specific asset regardless of its location. This is the primary subscription type for Asset Owners and Manufacturers tracking their own drones.
Access:
org_type= Asset Owner or Asset Manufacturer. The caller’s organisation must hold an active membership for the target asset. Access is resolved via org-level membership: individual user-level asset membership is also accepted.
Client → server (subscribe):
{
"action": "subscribe_asset",
"assetUuid": "6a485b00-e7ac-464e-af96-dbe78566a130"
}Server → client (response):
{
"type": "asset_subscription_response",
"assetUuid": "6a485b00-e7ac-464e-af96-dbe78566a130",
"message": "Successfully subscribed to asset"
}Client → server (unsubscribe):
{
"action": "unsubscribe_asset",
"assetUuid": "6a485b00-e7ac-464e-af96-dbe78566a130"
}Viewport (Bounding-Box) Subscription
Subscribe to the latest active telemetry for all assets inside the map area visible to this WebSocket connection. This is a third subscription mode on the same /v1/airspace/live WebSocket; it does not create a virtual zone or another WebSocket.
Access: active Member, Admin, or Owner of an active Airspace Manager organisation. Airspace Monitor organisations may use real-zone subscriptions but receive
ACCESS_DENIEDfor viewport actions.
Each physical connection has one replaceable viewport. Browser tabs use independent connections and therefore have independent viewports, even for the same user.
Client → server (set or replace bounds):
{
"action": "set_bounds",
"version": 0,
"bounds": {
"west": 77.1,
"south": 28.5,
"east": 77.3,
"north": 28.75
}
}Client → server (clear bounds):
{
"action": "clear_bounds",
"version": 1
}Versions are connection-local integers from 0 through 999. The first accepted viewport action must use 0; each accepted state change uses (current + 1) % 1000. Rejected actions do not consume the version. Do not order versions using greater-than comparisons.
Bounds use WGS84 longitude/latitude. Values must be finite, longitudes must be in [-180, 180], latitudes in [-90, 90], west \< east, and south \< north. Edges are inclusive. Antimeridian-crossing bounds are not supported in v1. The server accepts at most five successful viewport changes per connection in a rolling one-second window.
Map clients should reuse the same socket, send updates after map moveend, and debounce updates by 250 ms. A pan replaces the connection’s viewport without changing its zone or asset subscriptions.
After bounds_ack, the server emits zero or more viewport_snapshot events containing up to 200 current frames each, followed by viewport_snapshot_complete. The snapshot contains the latest fresh frame per matching asset; it is not historical telemetry. Live telemetry_frame events can be interleaved with snapshot events.
viewport_assets_removed identifies assets whose viewport source ended and supplies a reason of outside_bounds, stale, session_ended, or subscription_cleared. During a pan, retain existing markers until viewport_snapshot_complete, merge frames by asset_uuid and newest telemetry timestamp, then remove only the viewport source listed by the completion event. Keep a marker when a zone or explicit-asset source still supplies it.
Viewport state is process-local and deleted on disconnect. It is not a persisted airspace zone and never grants access to violation_alert; alerts still require an explicit real-zone subscription.
Incoming Telemetry Frame
Zone, asset, and viewport subscribers receive the same frame envelope. A connection receives no more than one telemetry_frame for an observation even when multiple subscription sources match.
{
"type": "telemetry_frame",
"data": {
"session_uuid": "f2d9a781-ef56-4233-a7fc-cb3e21a9cce4",
"asset_uuid": "6a485b00-e7ac-464e-af96-dbe78566a130",
"asset_uin": "UINIF1315",
"zone_uuids": [
"4f39caae-2a73-426e-bb0c-239e25a01a14"
],
"delivery_context": {
"zone_uuids": [
"4f39caae-2a73-426e-bb0c-239e25a01a14"
],
"asset_subscription": true,
"viewport_version": 7
},
"timestamp": "2026-06-16T07:32:15.000Z",
"latitude": 28.6145,
"longitude": 77.2093,
"altitude_agl": 45.2,
"absolute_altitude_m": 260.5,
"heading": 270,
"horizontal_speed": 12.4,
"vertical_speed": 0.3,
"climb_mps": 0.3,
"groundspeed_mps": 12.4,
"roll_deg": 2.1,
"pitch_deg": -1.5,
"yaw_deg": 270,
"gps_fix_type": 3,
"satellites_visible": 14,
"battery_remaining_percent": 82,
"battery_voltage_v": 22.4,
"battery_current_a": 18.5,
"is_armed": true,
"is_in_air": true,
"flight_mode": "AUTO",
"status_text": "Flying"
}
}For asset subscriptions,
zone_uuidslists the airspace zones the drone was inside at frame time: may be empty if flying outside any registered zone.
Error responses (invalid action, bad UUID, access denied):
{
"type": "error",
"message": "Access denied. Asset Owner or Asset Manufacturer organisation required.",
"code": "ACCESS_DENIED"
}Telemetry storage: Telemetry frames are written to the telemetry_frames hypertable (TimescaleDB) as they arrive. For the GCS inbound WebSocket, see Flight Sessions - Live Telemetry. For fetching stored frames, see GET /flight-sessions/\{session_uuid\}/telemetry/records.