GPSTrack

Track anything with one HTTP request

4 min read1 of 5 in Telematics

Most GPS tracking starts with an obstacle course: create an account, pick a plan, download an SDK, register a device, wait for approval. You wanted to see a dot move on a map.

This is the short version. Two HTTP requests and you have live tracking — one to get a session, one per point. No account, no key ceremony, no client library.

Get a session

A session is an identity to push points into, and a public id to read them back from. Ask for one:

curl -s -X POST https://gpstrack.dev/api/session
{
  "sessionId": "s_7f3a91c4",
  "token": "tk_9d41b0e6a7c2f5",
  "createdAt": 1781740800000,
  "expiresAt": 1784332800000,
  "retention": "ephemeral: relayed in-memory only, never stored on the server"
}

Two values matter, and the difference between them is the whole security model:

  • token is the write secret. Anything holding it can push points as you. It goes on the device and nowhere else.
  • sessionId is the public read id. It is what appears in a dashboard URL, and it cannot be used to write.

Push a point

curl "https://gpstrack.dev/api/ingest?token=tk_9d41b0e6a7c2f5&lat=6.9271&lng=79.8612"
{ "ok": true, "seq": 1, "expiresAt": 1784332800000 }

That is the entire ingest API. Open https://gpstrack.dev/app?view=live in a browser, and the point is on the map.

seq is the sequence number the relay assigned. The dashboard polls for everything after the last seq it saw, which is why you never get a duplicate and never need to send a timestamp to keep order straight.

The fields it understands

Only lat and lng are required. Everything else is optional, and anything the device does not know it should simply omit.

Parameter Aliases Meaning
lat latitude Degrees, required
lng lon, longitude Degrees, required
ts timestamp Epoch ms. Defaults to arrival time
speed speedKph Km/h
heading Degrees, 0 = north
altitude alt Metres
sats satellites Satellites in the fix
battery batteryLevel Percent
label A name for this tracker

The aliases exist because devices disagree. A GPS module that emits latitude and a phone script that emits lat should not need a translation layer between them, so the relay accepts both and normalises on the way in.

Anything not in that table becomes a custom channel rather than being discarded — &rpm=900&fuel=42.5 will show up as its own readout. That has an article of its own.

POST works too

Query strings are convenient from a shell and awkward from a device that already speaks JSON. Both are the same endpoint:

curl -X POST https://gpstrack.dev/api/ingest \
  -H "Content-Type: application/json" \
  -H "X-API-Key: tk_9d41b0e6a7c2f5" \
  -d '{"lat":6.9271,"lng":79.8612,"speed":42,"heading":118}'

The token can travel three ways: ?token=, an X-API-Key header, or Authorization: Bearer. Prefer a header over the query string wherever you have the choice — query strings end up in proxy logs and browser history in a way headers do not.

A tracker in five lines of shell

Nothing above needs a device. Here is a complete tracker that walks a point east along a line, which is enough to watch the map behave before real hardware exists:

TOKEN=tk_9d41b0e6a7c2f5
LAT=6.9271
LNG=79.8612

while true; do
  LNG=$(awk "BEGIN{print $LNG + 0.0004}")
  curl -s "https://gpstrack.dev/api/ingest?token=$TOKEN&lat=$LAT&lng=$LNG&speed=36" > /dev/null
  sleep 2
done

If you have a real GPS receiver on the machine, the same loop with gpspipe feeding it is a working tracker — that is the Raspberry Pi article.

The limits, stated plainly

One point per second per session, with a burst allowance of five. Go over it and you get a 429 with a Retry-After header rather than a silent drop:

{ "ok": false, "error": "rate limit: 1 point/sec per session (burst 5)" }

Rejecting rather than dropping is deliberate. A device that is over the limit can see why; points that vanish silently are undebuggable from the outside.

A thousand points per session, in memory. This is a relay, not a database. The buffer is a ring: point 1001 pushes point 1 out. At one point every two seconds that is a little over half an hour of history, which is the right size for live tracking and the wrong size for a trip log. Export to CSV or GPX as you go if you need to keep it.

Nothing on disk. The points are relayed through memory and never written to server storage. The session identity — the id and the token — is durable for 30 days from last use, so a device can keep pushing to the same session across reboots.

When this is the wrong tool

If you want a phone to record itself — a run, a ride, a walk — none of the above applies. There is no server round trip to make, and Track Me records to the phone's own storage instead. This article is for the case where the thing being tracked is not the thing displaying the map.

If you want durable history with queries over it, this is a relay and you want a database behind it. Pull points out with the read API and keep them yourself:

curl "https://gpstrack.dev/api/session/s_7f3a91c4/points?since=0"

Where to go next

Open the dashboard → Push points from any device over HTTP or MQTT and watch them move on a live map.
More on Telematics dashboard All 5 →
  1. Telematics

    Live-track a Raspberry Pi with a USB GPS dongle

    Plug in a u-blox dongle, read it with gpsd, and stream fixes to a live map from a shell script. Includes the systemd unit and the m/s to km/h trap.

    20 June 2026 · 4 min read

  2. Telematics

    Send custom telemetry alongside GPS

    Push rpm, fuel, voltage or water temperature on the same request as the position, and bind each one to a gauge, sparkline or compass. No schema to register.

    23 June 2026 · 4 min read

  3. Telematics

    HTTP or MQTT for GPS tracking? Pick by power budget

    Both deliver the same point. The difference is what a connection costs your device. A decision table, the handshake arithmetic, and where each one falls apart.

    25 June 2026 · 4 min read