Zones

Zone management

List all zones

get
Query parameters
searchstringOptional
categoryIdsstringOptional

Comma-separated category IDs

Responses
200

List of zones

application/json
get
/zones
GET /api/zones HTTP/1.1
Host: 
Accept: */*
[
  {
    "id": 1,
    "title": "text",
    "description": "text",
    "geojson": {},
    "userId": "text",
    "isGlobal": true,
    "map3dType": "text",
    "map3dUrl": "text",
    "map3dConfig": {},
    "categories": [
      {
        "category": {
          "id": 1,
          "name": "text",
          "description": "text",
          "color": "text",
          "createdAt": "2025-11-17T22:06:13.390Z"
        }
      }
    ],
    "pins": [
      {
        "id": 1,
        "title": "text",
        "latitude": 1,
        "longitude": 1,
        "geoPose": {},
        "contentType": "APK",
        "contentUrl": "text",
        "localizationData": {
          "trackingMode": "WORLD",
          "worldmapURL": "https://example.com"
        },
        "zoneId": 1,
        "gcpId": 1,
        "createdAt": "2025-11-17T22:06:13.390Z",
        "updatedAt": "2025-11-17T22:06:13.390Z"
      }
    ],
    "_count": {
      "pins": 1
    },
    "createdAt": "2025-11-17T22:06:13.390Z",
    "updatedAt": "2025-11-17T22:06:13.390Z"
  }
]

Create a new zone

post
Body
titlestringRequired
descriptionstringOptional
geojsonobjectRequired
categoryIdsinteger[]Optional
map3dTypestring | nullableOptional
map3dUrlstring | nullableOptional
map3dConfigobject | nullableOptional
Responses
post
/zones
POST /api/zones HTTP/1.1
Host: 
Content-Type: application/json
Accept: */*
Content-Length: 122

{
  "title": "text",
  "description": "text",
  "geojson": {},
  "categoryIds": [
    1
  ],
  "map3dType": "text",
  "map3dUrl": "text",
  "map3dConfig": {}
}
{
  "id": 1,
  "title": "text",
  "description": "text",
  "geojson": {},
  "userId": "text",
  "isGlobal": true,
  "map3dType": "text",
  "map3dUrl": "text",
  "map3dConfig": {},
  "categories": [
    {
      "category": {
        "id": 1,
        "name": "text",
        "description": "text",
        "color": "text",
        "createdAt": "2025-11-17T22:06:13.390Z"
      }
    }
  ],
  "pins": [
    {
      "id": 1,
      "title": "text",
      "latitude": 1,
      "longitude": 1,
      "geoPose": {},
      "contentType": "APK",
      "contentUrl": "text",
      "localizationData": {
        "trackingMode": "WORLD",
        "worldmapURL": "https://example.com"
      },
      "zoneId": 1,
      "gcpId": 1,
      "createdAt": "2025-11-17T22:06:13.390Z",
      "updatedAt": "2025-11-17T22:06:13.390Z"
    }
  ],
  "_count": {
    "pins": 1
  },
  "createdAt": "2025-11-17T22:06:13.390Z",
  "updatedAt": "2025-11-17T22:06:13.390Z"
}

Update a zone

put
Path parameters
idintegerRequired
Body
titlestringRequired
descriptionstringOptional
geojsonobjectOptional
categoryIdsinteger[]Optional
map3dTypestring | nullableOptional
map3dUrlstring | nullableOptional
map3dConfigobject | nullableOptional
Responses
200

Zone updated

application/json
put
/zones/{id}
PUT /api/zones/{id} HTTP/1.1
Host: 
Content-Type: application/json
Accept: */*
Content-Length: 122

{
  "title": "text",
  "description": "text",
  "geojson": {},
  "categoryIds": [
    1
  ],
  "map3dType": "text",
  "map3dUrl": "text",
  "map3dConfig": {}
}
{
  "id": 1,
  "title": "text",
  "description": "text",
  "geojson": {},
  "userId": "text",
  "isGlobal": true,
  "map3dType": "text",
  "map3dUrl": "text",
  "map3dConfig": {},
  "categories": [
    {
      "category": {
        "id": 1,
        "name": "text",
        "description": "text",
        "color": "text",
        "createdAt": "2025-11-17T22:06:13.390Z"
      }
    }
  ],
  "pins": [
    {
      "id": 1,
      "title": "text",
      "latitude": 1,
      "longitude": 1,
      "geoPose": {},
      "contentType": "APK",
      "contentUrl": "text",
      "localizationData": {
        "trackingMode": "WORLD",
        "worldmapURL": "https://example.com"
      },
      "zoneId": 1,
      "gcpId": 1,
      "createdAt": "2025-11-17T22:06:13.390Z",
      "updatedAt": "2025-11-17T22:06:13.390Z"
    }
  ],
  "_count": {
    "pins": 1
  },
  "createdAt": "2025-11-17T22:06:13.390Z",
  "updatedAt": "2025-11-17T22:06:13.390Z"
}

Delete a zone

delete
Path parameters
idintegerRequired
Responses
delete
/zones/{id}
DELETE /api/zones/{id} HTTP/1.1
Host: 
Accept: */*

No content

Get pins for a zone

get
Path parameters
idintegerRequired
Responses
200

List of pins in zone

application/json
get
/zones/{id}/pins
GET /api/zones/{id}/pins HTTP/1.1
Host: 
Accept: */*
[
  {
    "id": 1,
    "title": "text",
    "latitude": 1,
    "longitude": 1,
    "geoPose": {},
    "contentType": "APK",
    "contentUrl": "text",
    "localizationData": {
      "trackingMode": "WORLD",
      "worldmapURL": "https://example.com"
    },
    "zoneId": 1,
    "gcpId": 1,
    "createdAt": "2025-11-17T22:06:13.390Z",
    "updatedAt": "2025-11-17T22:06:13.390Z"
  }
]

Create a pin in a zone

post
Path parameters
idintegerRequired
Body
titlestringRequired
contentUrlstring · uriRequired
contentTypestring · enumRequiredPossible values:
gcpDatastringOptional
gcpTypestring · enumOptionalPossible values:
altitudenumberOptional
aprilTagIdinteger · max: 50Optional
photoUrlsstring · uri[] · max: 3Optional
Responses
post
/zones/{id}/pins
POST /api/zones/{id}/pins HTTP/1.1
Host: 
Content-Type: application/json
Accept: */*
Content-Length: 338

{
  "title": "text",
  "contentUrl": "https://example.com",
  "contentType": "IMAGE",
  "geoPose": {
    "position": {
      "lat": 1,
      "lon": 1,
      "h": 0
    },
    "angles": {
      "yaw": 0,
      "pitch": 0,
      "roll": 0
    }
  },
  "gcpData": "text",
  "gcpType": "SINGLE",
  "altitude": 1,
  "aprilTagId": 1,
  "photoUrls": [
    "https://example.com"
  ],
  "localizationData": {
    "trackingMode": "WORLD",
    "worldmapURL": "https://example.com"
  }
}
{
  "id": 1,
  "title": "text",
  "latitude": 1,
  "longitude": 1,
  "geoPose": {},
  "contentType": "APK",
  "contentUrl": "text",
  "localizationData": {
    "trackingMode": "WORLD",
    "worldmapURL": "https://example.com"
  },
  "zoneId": 1,
  "gcpId": 1,
  "createdAt": "2025-11-17T22:06:13.390Z",
  "updatedAt": "2025-11-17T22:06:13.390Z"
}

Create a GCP in a zone

post
Path parameters
idintegerRequired
Body
titlestringRequired
descriptionstringOptional
gcpTypestring · enumRequiredPossible values:
altitudenumberOptional
aprilTagIdinteger · max: 50Optional
gcpDatastringOptional
photoUrlsstring · uri[] · max: 3Optional
uploadedFileIdsinteger[]Optional
zoneIdintegerOptional
Responses
post
/zones/{id}/gcp
POST /api/zones/{id}/gcp HTTP/1.1
Host: 
Content-Type: application/json
Accept: */*
Content-Length: 255

{
  "title": "text",
  "description": "text",
  "gcpType": "SINGLE",
  "geoPose": {
    "position": {
      "lat": 1,
      "lon": 1,
      "h": 0
    },
    "angles": {
      "yaw": 0,
      "pitch": 0,
      "roll": 0
    }
  },
  "altitude": 1,
  "aprilTagId": 1,
  "gcpData": "text",
  "photoUrls": [
    "https://example.com"
  ],
  "uploadedFileIds": [
    1
  ],
  "zoneId": 1
}
{
  "gcp": {
    "id": 1,
    "title": "text",
    "description": "text",
    "gcpType": "SINGLE",
    "altitude": 1,
    "aprilTagId": 1,
    "gcpData": "text",
    "photoUrls": [
      "text"
    ],
    "zoneId": 1,
    "pin": {
      "id": 1,
      "title": "text",
      "latitude": 1,
      "longitude": 1,
      "geoPose": {},
      "contentType": "APK",
      "contentUrl": "text",
      "localizationData": {
        "trackingMode": "WORLD",
        "worldmapURL": "https://example.com"
      },
      "zoneId": 1,
      "gcpId": 1,
      "createdAt": "2025-11-17T22:06:13.390Z",
      "updatedAt": "2025-11-17T22:06:13.390Z"
    },
    "zone": {
      "id": 1,
      "title": "text"
    },
    "uploadedFiles": [
      {
        "id": 1,
        "fileName": "text",
        "fileUrl": "text",
        "fileSize": 1,
        "mimeType": "text",
        "bucketPath": "text",
        "gcpId": 1,
        "userId": "text",
        "uploadedAt": "2025-11-17T22:06:13.390Z"
      }
    ],
    "createdAt": "2025-11-17T22:06:13.390Z",
    "updatedAt": "2025-11-17T22:06:13.390Z"
  },
  "pin": {
    "id": 1,
    "title": "text",
    "latitude": 1,
    "longitude": 1,
    "geoPose": {},
    "contentType": "APK",
    "contentUrl": "text",
    "localizationData": {
      "trackingMode": "WORLD",
      "worldmapURL": "https://example.com"
    },
    "zoneId": 1,
    "gcpId": 1,
    "createdAt": "2025-11-17T22:06:13.390Z",
    "updatedAt": "2025-11-17T22:06:13.390Z"
  }
}

Check April tag availability in a zone

get
Path parameters
idintegerRequired
Query parameters
aprilTagIdinteger · max: 50Required
latitudenumberOptional
longitudenumberOptional
excludeGcpIdintegerOptional
Responses
200

April tag validation result

application/json
get
/zones/{id}/gcp/check-april-tag
GET /api/zones/{id}/gcp/check-april-tag?aprilTagId=1 HTTP/1.1
Host: 
Accept: */*
{
  "available": true,
  "conflicts": [
    {}
  ]
}

Get the global zone

get
Responses
200

Global zone

application/json
get
/zones/global-zone
GET /api/zones/global-zone HTTP/1.1
Host: 
Accept: */*
{
  "id": 1,
  "title": "text",
  "description": "text",
  "geojson": {},
  "userId": "text",
  "isGlobal": true,
  "map3dType": "text",
  "map3dUrl": "text",
  "map3dConfig": {},
  "categories": [
    {
      "category": {
        "id": 1,
        "name": "text",
        "description": "text",
        "color": "text",
        "createdAt": "2025-11-17T22:06:13.390Z"
      }
    }
  ],
  "pins": [
    {
      "id": 1,
      "title": "text",
      "latitude": 1,
      "longitude": 1,
      "geoPose": {},
      "contentType": "APK",
      "contentUrl": "text",
      "localizationData": {
        "trackingMode": "WORLD",
        "worldmapURL": "https://example.com"
      },
      "zoneId": 1,
      "gcpId": 1,
      "createdAt": "2025-11-17T22:06:13.390Z",
      "updatedAt": "2025-11-17T22:06:13.390Z"
    }
  ],
  "_count": {
    "pins": 1
  },
  "createdAt": "2025-11-17T22:06:13.390Z",
  "updatedAt": "2025-11-17T22:06:13.390Z"
}