Menu

GPS Lost Detection

The GPS Lost endpoint plays a critical role in monitoring the stability of internet infrastructure. It will detect outages in geographic areas and determine the magnitude of the damage caused by the attack and use this data to create an overview of the affected network segments, enabling rapid response and damage mitigation.

This article will explain how to interact with the Gatehouse Maritime API to create, read, update, or delete GPS Lost detectors, with concrete code examples of how to do it.

Content overview:

The base URL for the following endpoints is:

https://mdmdemo.gatehousemaritime.com/api/ingress/ais-gps-lost-detection

POST /grid-job-configs

To create a grounding detector, a configuration needs to be specified.

A configuration is specified in JSON format; an example of a specification can be seen below:

Configuration Example (JSON)

{
  "id": 1,
  "job_name": "test area gps lost",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-29"
  },
  "geometry_shape": {
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ],
    "type": "Polygon"
  },
  "enabled": True,
  "grid_cell_size_meters": 40000
}

The specification contains several parameters that can be tweaked to fit the use case.

  • “job_name”
    • The name of the configuration
  • “update_interval_hours”
    • Specifies the interval within which the number of lost signals will be aggregated.
  • “historical_range”
    • Here, a “lower” and “upper” key should be specified to describe the range in which the user can view the lost GPS signals.
  • “geometry_shape”
    • Here two key value pairs should be specified, i.e. “coordinates” and “type”.
      • “coordinates” describes the area that the GPS lost tracker should operate within in GeoJSON format.
      • “type” describes the type of the shape, e.g. “Polygon”, “Linestring”, “Point”.
  • “enabled”
    • Defines whether the tracker should be enabled and keep tracking.
  • “grid_cell_size_meters”
    • Defines the hexagons that make up the grid area. Each cell aggregates signals within its boundaries.

To create a GPS Lost configuration, construct a POST request via the /grid-job-configs route where the payload is the specification of the configuration, as shown above.

Example Code (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-configs"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json",
}

payload = {
  "id": 1,
  "job_name": "test area gps lost",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-29"
  },
  "geometry_shape": {
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ],
    "type": "Polygon"
  },
  "enabled": True,
  "grid_cell_size_meters": 40000
}

response = requests.post(URL, headers=headers, json=payload)
print(response.status_code)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

Response Sample

201
{
  "id": 1,
  "uuid": "9a427411-8918-42a3-b2b6-c7821effed73",
  "created_at": "2026-02-04T07:52:35.232751Z",
  "created_by": "mae",
  "modified_at": "2026-02-04T07:52:35.232776Z",
  "modified_by": "mae",
  "owner": "de5021f4-d4d2-49b6-acbe-4cf190370439",
  "acl": [],
  "job_name": "test area gps lost",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-29"
  },
  "shape_uuid": null,
  "geometry_shape": {
    "type": "Polygon",
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ]
  },
  "enabled": true,
  "grid_cell_size_meters": 40000
}

GET /grid-job-results/{job_id}/results

As a prerequisite, the id of the configuration needs to be known. If the id of the configuration is not known, see Get all configured GPS Lost configurations to locate the id. Additionally, the start time and end time of the time period also needs to be known and if this is not known, see Get all GPS Lost instances.

To get the results of a GPS Lost configuration, construct a GET request via the /grid-job-results/{job_id}/results endpoint and here, the id of the configuration, start time and end time should be specified in the header.

Example Code (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-results/{job_id}/results?start_time=<start_time>&end_time=<end_time>"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json"
}

response = requests.get(URL, headers=headers)
print(response.status_code)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

In this example code, the job_id value is the id of the configuration and the start_time and end_time values describe the interval and is of the form “YYYY-MM-DDTHH:MM:SSZ“.

Response Sample

200
[
  {
    "job_id": 51,
    "job_instance_id": 826,
    "timerange": {
      "lower": "2025-10-04T18:00:00Z",
      "upper": "2025-10-05T00:00:00Z"
    },
    "status": "success",
    "grid_cells_result": [
      {
        "element_id": 731,
        "ships_w_lost_gps": 1,
        "mmsi_list": [
          246141000
        ]
      },
      {
        "element_id": 850,
        "ships_w_lost_gps": 1,
        "mmsi_list": [
          246141000
        ]
      },
      {
        "element_id": 971,
        "ships_w_lost_gps": 1,
        "mmsi_list": [
          246141000
        ]
      }
    ] 
  }
]

DELETE /grid-job-configs/{job_id}

As a prerequisite to deleting a configuration, the id of the configuration should be known, if this is not the case, see Get all configured GPS Lost configurations and find the id of the configuration.

To delete a GPS Lost configuration, construct a DELETE request via the /grid-job-configs/{job_id} where the job_id variable is the id of the configuration.

Example Code (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-configs/{job_id}"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json",
}
    
response = requests.delete(URL, headers=headers)
print(response.status_code)

Response Sample

204

PUT /grid-job-configs/{job_id}

As a prerequisite to updating a configuration, the id of the configuration and “owner” key value pair should be known and the updated configuration should be specified.

To update a GPS Lost configuration, construct a PUT request via the /grid-job-configs/{job_id} endpoint, where the job_id variable is the id of the configuration and the request body should contain the specification of the updated configuration.

Configuration Example (JSON)

{
  "id": 1,
  "owner": "de5091f5-c4d3-49b6-acbe-4cf190370439",
  "job_name": "test area gps lost",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-29"
  },
  "geometry_shape": {
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ],
    "type": "Polygon"
  },
  "enabled": True,
  "grid_cell_size_meters": 40000
}

The specification contains several parameters that can be tweaked to fit the use case.

  • “job_name”
    • The name of the configuration
  • “owner”
    • The uuid of the configurations’ creator
  • “update_interval_hours”
    • Specifies the interval within which the number of lost signals will be aggregated.
  • “historical_range”
    • Here, a “lower” and “upper” key should be specified to describe the range in which the user can view the lost GPS signals.
  • “geometry_shape”
    • Here two key value pairs should be specified, i.e. “coordinates” and “type”.
      • “coordinates” describes the area that the GPS lost tracker should operate within in GeoJSON format.
      • “type” describes the type of the shape, e.g. “Polygon”, “Linestring”, “Point”.
  • “enabled”
    • Defines whether the tracker should be enabled and keep tracking.
  • “grid_cell_size_meters”
    • Defines the hexagons that make up the grid area. Each cell aggregates signals within its boundaries.

Code Example (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-configs/{job_id}"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json",
}

payload = {
  "id": 1,
  "owner": "ae5211g5-c4d3-49b6-acbe-4bf190370439",
  "job_name": "Test1",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-29"
  },
  "geometry_shape": {
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ],
    "type": "Polygon"
  },
  "enabled": True,
  "grid_cell_size_meters": 40000
}

response = requests.put(URL, headers=headers, json=payload)
print(response.status_code)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

Response Sample

200
{
  "id": 1,
  "uuid": "c15db372-2387-4d08-9eb5-1902479a17c5",
  "created_at": "2026-02-04T09:24:44.913174Z",
  "created_by": "mae",
  "modified_at": "2026-02-04T09:34:31.941128Z",
  "modified_by": "mae",
  "owner": "ae5211g5-c4d3-49b6-acbe-4bf190370439",
  "acl": null,
  "job_name": "Test2",
  "update_interval_hours": 24,
  "historical_range": {
    "lower": "2025-12-30",
    "upper": "2026-01-30"
  },
  "shape_uuid": null,
  "geometry_shape": {
    "type": "Polygon",
    "coordinates": [
      [
        [
          7.77392578124999,
          54.39828335627755
        ],
        [
          12.74267578125001,
          58.62129400565829
        ],
        [
          16.63232421875,
          55.41381508026815
        ],
        [
          7.77392578124999,
          54.39828335627755
        ]
      ]
    ]
  },
  "enabled": true,
  "grid_cell_size_meters": 40000
}

GET /grid-job-configs

To get all the current configurations of GPS Lost trackers, construct a GET request via the /grid-job-configs route.

/grid-job-configs

This will return a JSON object containing all specifications of configurations.

Example code (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-configs"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json",
    "page": "<num_of_pages>",
    "size": "<page_size>"
}

response = requests.get(URL, headers=headers)
print(response.status_code)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

Response sample

200
{
  "items": [
    {
      "id": 21,
      "uuid": "e25d0f29-f390-42b7-b689-1e738636826e",
      "created_at": "2025-05-09T06:43:51.812932Z",
      "created_by": "user",
      "modified_at": "2025-05-09T06:43:51.813879Z",
      "modified_by": "user",
      "owner": "dc4af834-235e-421a-91d1-f95b98027660",
      "acl": [],
      "job_name": "test area gps lost",
      "update_interval_hours": 24,
      "historical_range": {
        "lower": "2025-05-03",
        "upper": "2025-05-07"
      },
      "shape_uuid": "dd795e8c-3a0d-4c0d-82fe-36e4ba82811f",
      "geometry_shape": null,
      "enabled": true,
      "grid_cell_size_meters": 40000
    }
}

GET /grid-job-configs/{job_id}/instances

To get the instances of a GPS Lost configuration, construct a GET request via the /grid-job-configs/{job_id}/instances.

Code Example (Python)

import requests
import json

URL = (
    f"https://demo.ghmaritime.com/api/ingress/ais-gps-lost-detection/grid-job-configs/{job_id}/instances"
)
headers = {
    "Authorization": "Basic <credentials>",
    "accept": "application/json",
    "page": "<num_of_pages>",
    "size": "<page_size>"
}

response = requests.get(URL, headers=headers)
print(response.status_code)
response.raise_for_status()
print(json.dumps(response.json(), indent=2))

Response Sample

200
{
  "items": [
    {
      "id": 823,
      "uuid": "af2bb62e-c0fb-4bb9-ac9a-bd5e969adbfd",
      "created_at": "2025-10-06T12:56:18.112724Z",
      "created_by": "mae",
      "modified_at": "2025-10-06T13:05:41.204768Z",
      "modified_by": "grid_job_scheduler",
      "job_id": 51,
      "timerange": {
        "lower": "2025-10-04T00:00:00Z",
        "upper": "2025-10-04T06:00:00Z"
      },
      "status": "success",
      "started_at": "2025-10-06T13:03:24.730117Z",
      "finished_at": "2025-10-06T13:05:41.203526Z",
      "log_message": "GPS lost grid calculated successfully"
    },
    ...
  ]
}

It is then possible to use the id of the instances to get the results of the configuration.

Updated on 04 February, 2026