GPX Tracker API Documentation

Base URL: https://gpx.octal.be

Available Devices

Devices: moto1, moto2

/api/devices

Lists all available devices

curl -X GET "https://gpx.octal.be/api/devices"

Live Response:

{
  "path": "/api/devices",
  "value": [
    "heli1",
    "moto1",
    "moto2"
  ]
}

/api/standing

Current race standings and device aliases

curl -X GET "https://gpx.octal.be/api/standing"

Live Response:

{
  "path": "/api/standing",
  "value": {
    "first": "moto1",
    "second": "moto2"
  }
}

/api/position/moto1

Current position of moto1 (lat/lon)

curl -X GET "https://gpx.octal.be/api/position/moto1"

Live Response:

{
  "path": "/api/position/moto1",
  "value": {
    "latitude": 45.463093,
    "longitude": 7.135212
  }
}

/api/status/moto1

Health/status of moto1

curl -X GET "https://gpx.octal.be/api/status/moto1"

Live Response:

{
  "path": "/api/status/moto1",
  "value": "offline"
}

/api/gap/distance/moto1/start

Distance from start for moto1 (km)

curl -X GET "https://gpx.octal.be/api/gap/distance/moto1/start"

Live Response:

{
  "path": "/api/gap/distance/moto1/start",
  "unit": "km",
  "value": 129.8
}

/api/gap/distance/moto1/end

Distance to end for moto1 (km)

curl -X GET "https://gpx.octal.be/api/gap/distance/moto1/end"

Live Response:

{
  "path": "/api/gap/distance/moto1/end",
  "unit": "km",
  "value": 0.0
}

/api/speed/moto1/mean/50

Mean speed for moto1 over 50 points (km/h)

curl -X GET "https://gpx.octal.be/api/speed/moto1/mean/50"

Live Response:

{
  "path": "/api/speed/moto1/mean/50",
  "unit": "km/h",
  "value": 5
}

/api/speed/moto1/mean/50/text

Mean speed for moto1 — plain-text output

curl -X GET "https://gpx.octal.be/api/speed/moto1/mean/50/text"

Live Response:

{
  "raw": "5 km/h"
}

/api/poi/elevation/moto1

Current elevation for moto1 (m)

curl -X GET "https://gpx.octal.be/api/poi/elevation/moto1"

Live Response:

{
  "path": "/api/poi/elevation/moto1",
  "unit": "m",
  "value": 2242
}

/api/poi/slope/moto1

Current slope for moto1 (%)

curl -X GET "https://gpx.octal.be/api/poi/slope/moto1"

Live Response:

{
  "path": "/api/poi/slope/moto1",
  "unit": "%",
  "value": 1
}

/api/position/moto2

Current position of moto2 (lat/lon)

curl -X GET "https://gpx.octal.be/api/position/moto2"

Live Response:

{
  "path": "/api/position/moto2",
  "value": {
    "latitude": 45.463008,
    "longitude": 7.135724
  }
}

/api/status/moto2

Health/status of moto2

curl -X GET "https://gpx.octal.be/api/status/moto2"

Live Response:

{
  "path": "/api/status/moto2",
  "value": "offline"
}

/api/gap/distance/moto2/start

Distance from start for moto2 (km)

curl -X GET "https://gpx.octal.be/api/gap/distance/moto2/start"

Live Response:

{
  "path": "/api/gap/distance/moto2/start",
  "unit": "km",
  "value": 129.8
}

/api/gap/distance/moto2/end

Distance to end for moto2 (km)

curl -X GET "https://gpx.octal.be/api/gap/distance/moto2/end"

Live Response:

{
  "path": "/api/gap/distance/moto2/end",
  "unit": "km",
  "value": 0.0
}

/api/speed/moto2/mean/50

Mean speed for moto2 over 50 points (km/h)

curl -X GET "https://gpx.octal.be/api/speed/moto2/mean/50"

Live Response:

{
  "path": "/api/speed/moto2/mean/50",
  "unit": "km/h",
  "value": 4
}

/api/speed/moto2/mean/50/text

Mean speed for moto2 — plain-text output

curl -X GET "https://gpx.octal.be/api/speed/moto2/mean/50/text"

Live Response:

{
  "raw": "4 km/h"
}

/api/poi/elevation/moto2

Current elevation for moto2 (m)

curl -X GET "https://gpx.octal.be/api/poi/elevation/moto2"

Live Response:

{
  "path": "/api/poi/elevation/moto2",
  "unit": "m",
  "value": 2242
}

/api/poi/slope/moto2

Current slope for moto2 (%)

curl -X GET "https://gpx.octal.be/api/poi/slope/moto2"

Live Response:

{
  "path": "/api/poi/slope/moto2",
  "unit": "%",
  "value": 1
}

/api/gap/time/moto1/moto2

Time gap moto1↔moto2 — seconds (default)

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2"

Live Response:

{
  "path": "/api/gap/time/moto1/moto2",
  "unit": "s",
  "value": 0
}

/api/gap/time/moto1/moto2/mmss

Time gap — mm:ss format

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2/mmss"

Live Response:

{
  "path": "/api/gap/time/moto1/moto2/mmss",
  "unit": "",
  "value": "00:00"
}

/api/gap/time/moto1/moto2/hhmmss

Time gap — hh:mm:ss format

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2/hhmmss"

Live Response:

{
  "path": "/api/gap/time/moto1/moto2/hhmmss",
  "unit": "",
  "value": "00:00:00"
}

/api/gap/time/moto1/moto2/racing

Time gap — racing format (mm'ss'')

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2/racing"

Live Response:

{
  "path": "/api/gap/time/moto1/moto2/racing",
  "unit": "",
  "value": "00'00''"
}

/api/gap/time/moto1/moto2/racing/text

Time gap — racing, plain-text output

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2/racing/text"

Live Response:

{
  "raw": "00'00''"
}

/api/gap/time/moto1/moto2/hhmmss/html

Time gap — hh:mm:ss, HTML output

curl -X GET "https://gpx.octal.be/api/gap/time/moto1/moto2/hhmmss/html"

Live Response:

{
  "raw": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=300, height=100, initial-scale=1\">\n  <style>\n    body {\n      margin: 0;\n      padding: 10px;\n      font-family: Arial, sans-serif;\n      font-size: 48px;\n      font-weight: bold;\n      color: #333;\n      background: #f0f0f0;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      height: 80px;\n      width: 280px;\n    }\n  </style>\n  <script>\n  function updateValue() {\n    fetch(window.location.href)\n      .then(response => response.text())\n      .then(html => {\n        const parser = new DOMParser();\n        const doc = parser.parseFromString(html, 'text/html');\n        const newValue = doc.querySelector('#value');\n        if (newValue) {\n          document.getElementById('value').innerHTML = newValue.innerHTML;\n        }\n      })\n      .catch(err => console.error('Update failed:', err));\n  }\n  setInterval(updateValue, 5000);\n</script>\n\n</head>\n<body>\n  <div id=\"value\">00:00:00</div>\n</body>\n</html>\n"
}

/api/gap/distance/moto1/moto2

Distance gap moto1↔moto2 (km, JSON)

curl -X GET "https://gpx.octal.be/api/gap/distance/moto1/moto2"

Live Response:

{
  "path": "/api/gap/distance/moto1/moto2",
  "unit": "km",
  "value": 0.0
}

/api/gap/distance/moto1/moto2/text

Distance gap — plain-text output

curl -X GET "https://gpx.octal.be/api/gap/distance/moto1/moto2/text"

Live Response:

{
  "raw": "0.0 km"
}

/api/gap/time/first/second/racing

Time gap leader↔2nd (racing) — via aliases

curl -X GET "https://gpx.octal.be/api/gap/time/first/second/racing"

Live Response:

{
  "path": "/api/gap/time/first/second/racing",
  "unit": "",
  "value": "00'00''"
}

/api/gap/distance/first/last

Distance gap leader↔last — via aliases

curl -X GET "https://gpx.octal.be/api/gap/distance/first/last"

Live Response:

{
  "path": "/api/gap/distance/first/last",
  "unit": "km",
  "value": 0.0
}

Data refreshes every 5 seconds. Last update: 2026-09-01T08:32:29.599794Z