Skip to Content
APIsAirspace Zones

Access: Zone create and update require org_type = Airspace Manager, Admin+. Reads are open to authenticated organisations. See Access control. Manager and Monitor delegation routes are shortcuts to the Resource Memberships API.

Manages airspace zones. Zones are created and owned by the platform or organisations with org_type = Airspace Manager. Airspace Zone Memberships (Manager/Monitor) are managed via the Resource Memberships API.

Data Models: Airspace Zone

Enums: airspace_restriction_type, airspace_zone_type. See Enums.


Airspace Zone Endpoints Summary

EndpointMethodOperation NameDescription
/airspacesPOSTCreate ZoneCreate a new airspace zone
/airspaces/bulkPOSTBulk Create ZonesCreate multiple airspace zones in one request
/airspacesGETGet ZonesList all airspace zones
/airspaces/sync/checkGETSync CheckCheck whether zone catalog needs refresh
/airspaces/syncGETSync ZonesDownload zone catalog sync payload
/airspaces/\{zone_uuid\}GETGet One ZoneGet specific zone details
/airspaces/\{zone_uuid\}PUTUpdate ZoneUpdate a zone
/airspaces/\{zone_uuid\}DELETEDelete ZoneSoft delete a zone
/airspaces/\{zone_uuid\}/invitationsPOSTInvite OrganisationDelegate manager/monitor access to another org
/airspaces/\{zone_uuid\}/invitationsGETGet Zone InvitationsView pending manager/monitor invites
/airspaces/\{zone_uuid\}/invitations/acceptPOSTAccept Zone InviteAccept or decline a zone membership invite
/airspaces/\{zone_uuid\}/memberships/\{membership_uuid\}DELETERevoke Org MembershipRemove an organisation’s link to this zone

Create Zone

POST /airspaces

Create a new airspace restriction zone. Only accessible by platform admins or orgs with org_type = Airspace Manager.

Request Body:

{ "zone_name": "Northern Sector Restricted Zone", "restriction_type": 1, "airspace_zone_type": 1, "zone_envelope": { "type": "Polygon", "coordinates": [ [ [ 77.12345, 28.56789 ], [ 77.1245, 28.5678 ], [ 77.1246, 28.5667 ], [ 77.1234, 28.5666 ], [ 77.12345, 28.56789 ] ] ] }, "min_height": 0, "max_height": 400, "active_from": null, "active_to": null }
FieldTypeDescription
restriction_typeintairspace_restriction_type enum
airspace_zone_typeintairspace_zone_type enum (RED, YELLOW, etc.)
zone_envelopeGeoJSON PolygonGeographic boundary of the zone
active_from / active_totimestamp (nullable)Validity window for temporary restrictions

Responses:

  • 201 Created:
{ "message": "Airspace zone created successfully", "data": { ... } }
  • 400 Bad Request:
{ "error": "'restriction_type' must be a valid airspace restriction type enum" }
  • 409 Conflict:
{ "error": "An airspace zone with this name already exists" }
  • 422 Unprocessable Entity:
{ "error": "'zone_envelope' must be a valid closed GeoJSON Polygon" }

Bulk Create Zones

POST /airspaces/bulk

Create multiple airspace restriction zones in a single batch operation (useful for large-scale geometry updates).

Request Body:

{ "zones": [ { "zone_name": "Red Zone A", "restriction_type": 1, "airspace_zone_type": 1, "zone_envelope": { "type": "Polygon", "coordinates": [ ... ] } }, { "zone_name": "Red Zone B", "restriction_type": 1, "airspace_zone_type": 1, "zone_envelope": { "type": "Polygon", "coordinates": [ ... ] } } ] }

Responses:

  • 201 Created:
{ "message": "Bulk zone creation successful", "data": { "total_created": 2, "zones": [ ... ] } }
  • 400 Bad Request:
{ "error": "'zones' array must not be empty" }

Get Zones

GET /airspaces

List all active airspace restriction zones. Open to all authenticated organisations: Airspace Managers, asset owners, and any other org type can call this endpoint. Returns zone_envelope geometry in-line (no separate constraint call needed).

Query Parameters:

ParamTypeDescription
restriction_typeint (optional)Filter by airspace_restriction_type
airspace_zone_typeint (optional)Filter by airspace_zone_type
pageint (optional)Page number (default: 1)
limitint (optional)Records per page (default: 25)

Responses:

  • 200 OK:
{ "data": [ { "zone_uuid": "4f39caae-2a73-426e-bb0c-239e25a01a14", "zone_udai_id": "UDAI-ZONE-0301", "zone_name": "Northern Sector Restricted Zone", "org_owner_uuid": "550e8400-0000-41d4-a716-446655440000", "restriction_type": 1, "airspace_zone_type": 1, "constraint_uuid": "b7c8d9e0-f1a2-4b3c-8d4e-5f6a7b8c9d0e", "min_height": 0, "max_height": 400, "zone_envelope": { "type": "Polygon", "coordinates": [ [ [ 77.12345, 28.56789 ], [ 77.1245, 28.5678 ], [ 77.1246, 28.5667 ], [ 77.1234, 28.5666 ], [ 77.12345, 28.56789 ] ] ] }, "active_from": null, "active_to": null, "status": 1, "created_at": "2025-07-04T09:00:00Z", "updated_at": "2025-07-04T12:00:00Z" } ], "pagination": { "total_records": 1, "total_pages": 1, "current_page": 1, "per_page": 25, "has_next": false, "has_previous": false } }

Sync Check

GET /airspaces/sync/check

Returns the platform high-water mark for airspace zone changes so an adapter can decide whether a sync is needed.

Access: MemberPlus (authenticated organisation member).

Query Parameters:

ParamTypeDescription
after_change_idlong (optional)Client’s last applied change ID. Defaults to 0. Must be ≥ 0.

Responses:

  • 200 OK:
{ "current_change_id": 1842, "client_change_id": 1800, "has_changes": true, "full_sync_required": false }
FieldTypeDescription
current_change_idlongLatest change ID on the server
client_change_idlongEcho of the client’s after_change_id
has_changesbooltrue when current_change_id > client_change_id
full_sync_requiredbooltrue when the client’s change ID is below the retained history minimum: caller must run mode=full
  • 400 Bad Request: after_change_id is negative.

Adapter flow: Call sync check on a timer. If full_sync_required, run GET /airspaces/sync?mode=full. Else if has_changes, run GET /airspaces/sync?mode=diff\&after_change_id=\{client_change_id\}.


Sync Zones

GET /airspaces/sync

Downloads either a full zone catalog snapshot page or an incremental change page. Used by the Windows adapter (and other offline caches) to keep a local zone map current.

Access: MemberPlus.

Query Parameters:

ParamTypeDescription
modestring (required)full for a stable snapshot page, or diff for incremental changes
snapshot_change_idlong (optional)Full mode only. Pins the snapshot watermark; defaults to current high-water mark. Must be between 0 and current_change_id.
after_zone_idint (optional)Full mode cursor. Return zones with zone_id greater than this value. Defaults to 0.
after_change_idlong (required for diff)Diff mode: return changes strictly after this change ID
until_change_idlong (optional)Diff mode upper bound; defaults to current high-water mark. Must be between after_change_id and current inclusive.
limitint (optional)Page size. Default 500, max 500.

Full mode (mode=full)

Stable keyed pagination over the active zone catalog. Page through with after_zone_id / next_zone_id until has_more is false. Record snapshot_change_id as the client’s baseline before applying subsequent diffs.

Response (200 OK):

{ "mode": "full", "snapshot_change_id": 1842, "next_zone_id": 500, "has_more": true, "zones": [ { "zone_id": 1, "zone_uuid": "4f39caae-2a73-426e-bb0c-239e25a01a14", "zone_udai_id": "UDAI-ZONE-0301", "zone_version": 3, "zone_name": "Northern Sector Restricted Zone", "org_owner_uuid": "550e8400-0000-41d4-a716-446655440000", "restriction_type": 1, "airspace_zone_type": 1, "constraint_uuid": "b7c8d9e0-f1a2-4b3c-8d4e-5f6a7b8c9d0e", "min_height": 0, "max_height": 400, "active_from": null, "active_to": null, "status": 1, "created_at": "2025-07-04T09:00:00Z", "updated_at": "2025-07-04T12:00:00Z", "zone_envelope": { "type": "Polygon", "coordinates": [ [ [ 77.12345, 28.56789 ], [ 77.1245, 28.5678 ], [ 77.1246, 28.5667 ], [ 77.1234, 28.5666 ], [ 77.12345, 28.56789 ] ] ] } } ] }

Diff mode (mode=diff)

Returns change log entries between after_change_id and until_change_id. Each change includes an operation (upsert / delete) and, for upserts, a full zone snapshot.

Response (200 OK):

{ "mode": "diff", "from_change_id": 1800, "to_change_id": 1842, "next_change_id": 1842, "has_more": false, "changes": [ { "change_id": 1841, "operation": "upsert", "zone_uuid": "4f39caae-2a73-426e-bb0c-239e25a01a14", "zone_version": 4, "zone": { "zone_id": 1, "zone_uuid": "4f39caae-2a73-426e-bb0c-239e25a01a14", "zone_udai_id": "UDAI-ZONE-0301", "zone_version": 4, "zone_name": "Northern Sector Restricted Zone", "org_owner_uuid": "550e8400-0000-41d4-a716-446655440000", "restriction_type": 1, "airspace_zone_type": 1, "constraint_uuid": "b7c8d9e0-f1a2-4b3c-8d4e-5f6a7b8c9d0e", "min_height": 0, "max_height": 400, "active_from": null, "active_to": null, "status": 1, "created_at": "2025-07-04T09:00:00Z", "updated_at": "2025-07-04T12:30:00Z", "zone_envelope": { "type": "Polygon", "coordinates": [ [ [ 77.12345, 28.56789 ], [ 77.1245, 28.5678 ], [ 77.1246, 28.5667 ], [ 77.1234, 28.5666 ], [ 77.12345, 28.56789 ] ] ] } } }, { "change_id": 1842, "operation": "delete", "zone_uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "zone_version": 2, "zone": null } ] }

Error responses:

  • 400 Bad Request: Invalid mode, missing after_change_id for diff, out-of-range limit / IDs, or bad snapshot bounds.
  • 409 Conflict: change history for the requested after_change_id has been pruned:
{ "error": "FULL_SYNC_REQUIRED", "message": "The requested change history is no longer available" }

Caller must discard local state and re-run mode=full.


Get One Zone

GET /airspaces/{zone_uuid}

Responses:

  • 200 OK:
{ "data": { "zone_uuid": "4f39caae-2a73-426e-bb0c-239e25a01a14", "zone_udai_id": "UDAI-ZONE-0301", "zone_name": "Northern Sector Restricted Zone", "restriction_type": 1, "airspace_zone_type": 1, "zone_envelope": { "type": "Polygon", "coordinates": [ [ [ 77.12345, 28.56789 ], [ 77.1245, 28.5678 ], [ 77.1246, 28.5667 ], [ 77.1234, 28.5666 ], [ 77.12345, 28.56789 ] ] ] }, "min_height": 0, "max_height": 400, "active_from": null, "active_to": null, "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 } ], "status": 1, "created_at": "2025-07-04T09:00:00Z", "updated_at": "2025-07-04T12:00:00Z" } }
  • 404 Not Found:
{ "error": "Airspace zone not found" }
  • 410 Gone:
{ "error": "Airspace zone has been deactivated" }

Update Zone

PUT /airspaces/{zone_uuid}

Request Body:

{ "zone_name": "string", "restriction_type": "int", "airspace_zone_type": "int", "zone_envelope": "GeoJSON Polygon", "min_height": "double", "max_height": "double", "active_from": "timestamp", "active_to": "timestamp" }

Responses:

  • 200 OK:
{ "message": "Airspace zone updated successfully", "data": { ... } }
  • 400 Bad Request:
{ "error": "'restriction_type' must be a valid enum value" }
  • 404 Not Found:
{ "error": "Airspace zone not found" }
  • 422 Unprocessable Entity:
{ "error": "'zone_envelope' must be a valid closed GeoJSON Polygon" }

Soft Delete Zone

DELETE /airspaces/{zone_uuid}

Soft deletes an airspace zone (marks it inactive) and removes its associated constraint.

Responses:

  • 200 OK:
{ "message": "Airspace zone deleted successfully", "data": null }
  • 403 Forbidden:
{ "error": "Only Airspace Manager organisations can create/update/delete zones" }
  • 404 Not Found:
{ "error": "Airspace zone not found" }

Zone Memberships & Invitations

The following routes are fully implemented shortcut endpoints under /airspaces/.... Internally they delegate to the unified Resource Memberships API service layer.

POST /airspaces/{zone_uuid}/invitations

Invite another organisation to manage or monitor this zone.

  • Implementation mapping: POST /resource-invitations with resource_type=3 and resource_uuid=\{zone_uuid\}

GET /airspaces/{zone_uuid}/invitations

View all pending or past membership invitations for this zone.

  • Implementation mapping: GET /resource-invitations?resource_type=3&resource_uuid=\{zone_uuid\}

POST /airspaces/{zone_uuid}/invitations/accept

Accept or decline a pending membership invitation for this zone.

  • Implementation mapping: POST /resource-invitations/accept

DELETE /airspaces/{zone_uuid}/memberships/{membership_uuid}

Revoke an organisation’s membership (Manager/Monitor) for this zone.

  • Implementation mapping: DELETE /resource-memberships/\{membership_uuid\}
Last updated on