The API

One public URL that returns where someone is, right now. No key, no SDK. If it can read a web address, it can read a location. It answers where, not when — no arrival dates, no history, just the current place.

Read a location

GET /v1/{id}

Returns JSON with Access-Control-Allow-Origin: *, cached 30 seconds at the edge. Add ?format=text for a bare line, or ?format=svg for a badge you can drop into an <img> tag.

{
  "schema": "whereabouts/v1",
  "id": "k7m2p9x4qn8wr3fd",
  "precision": "city",
  "updatedAt": "2026-08-08T19:34:01Z",
  "stale": false,
  "location": {
    "displayName": "Nevada",
    "country": { "code": "US", "name": "United States", "flag": "🇺🇸" },
    "state": { "code": "NV", "name": "Nevada" },
    "city": "Las Vegas",
    "coordinates": null,
    "timeZone": {
      "identifier": "America/Los_Angeles",
      "offsetMinutes": -420,
      "localTime": "12:39"
    }
  }
}

Use it

const res = await fetch("https://getwhereabouts.com/v1/k7m2p9x4qn8wr3fd")
const where = await res.json()

document.querySelector("#where").textContent = where.location.displayName

Why the ids look like that

Ids are sixteen random characters minted by the server. There is no directory, no username and nothing to enumerate — knowing someone’s name gets you no closer to their location. The link is the only key, which is why it needs no other authentication, and why replacing it is one tap in the app.

Treat a link like a password that happens to be a URL: unguessable, but readable by anyone you hand it to. Every response is served noindex.

The fields

precision
region, city or exact, chosen by the person publishing. coordinates are non-null only at exact; at region, city is null too. Stripped on write and again on read, not merely hidden.
stale
True when the phone hasn’t checked in for six hours. The location is still the last known one — a hint, not a fault.
location.displayName
The one string to show if you only show one thing. A US state name, or a country name everywhere else.

Publish a location

The iOS app does this for you. The wire protocol is three calls, in case you want your own publisher.

POST   /v1/links     → { id, token, url }
PUT    /v1/{id}    Authorization: Bearer <token>
DELETE /v1/{id}    Authorization: Bearer <token>

POST /v1/links takes no body — the server mints the id, so there is no name to look anyone up by. PUT takes the document above minus the server-derived id and stale. DELETE empties the link; add ?release=1 to destroy it for good.