Ooru

API

Three GET endpoints, no key, no rate limit, CORS open to everything. Encoding and decoding are pure functions over a committed word table, so every response is deterministic and cacheable forever — the routes are statically rendered and served from the edge.

GET /api/encode

Coordinates → address.

ParameterRequiredMeaning
latyesWGS84 latitude in degrees
lngyesWGS84 longitude in degrees
depthnoHow many words to return, 1–4. Defaults to 3.
curl "https://…/api/encode?lat=13.0499&lng=80.2824"

Returns the address, the per-word breakdown with each word’s level and semantic group, the cell centre in both CRSs, the point scale factor there, the footprint as GeoJSON, and the chain of containing addresses.

{ "address": "cavern.organza.panther", "display": "///cavern.organza.panther", "depth": 3, "centre": { "crs": "EPSG:4326", "lat": …, "lng": … }, "projected": { "crs": "EPSG:32644", "easting": …, "northing": …, "pointScaleFactor": … }, "cell": { "sizeMetres": 12.5, "areaSquareMetres": 156.25, "bounds": { … }, "polygon": { "type": "Polygon", … } }, "contains": [ { "address": "…", "depth": 1, … } ] }
Abridged; the real response also carries the per-word breakdown and the containment chain.

A position outside the coverage area returns 422 with error: "out_of_extent" rather than a nonsense address.

GET /api/decode

Address → coordinates. Same response shape as encode.

ParameterRequiredMeaning
addressyesThe address. Dots, spaces or slashes all work, and a leading /// is accepted.
risknoSet to include the confusion set — the plausible wrong addresses and how far each lands you.
{ "error": "unknown-word", "message": "\"rivver\" is not a Ooru word", "position": 0, "token": "rivver", "suggestions": [ { "word": "river", "level": 1, "index": …, "distance": 1 } ] }

A word in the wrong slot returns error: "wrong-level", which a flat scheme cannot detect at all — with one global vocabulary, any word is legal in any position.

GET /api/neighbours

The eight cells touching an address, with the true ground distance to each centre. This endpoint has no equivalent in a non-topological scheme.

{ "address": "cavern.organza.panther", "cellSizeMetres": 12.5, "neighbours": [ { "direction": "E", "address": "…", "centre": {…}, "distanceMetres": 12.5 }, { "direction": "NE", "address": "…", "centre": {…}, "distanceMetres": 17.678 }, … ] }
Diagonal distances come back as √2 × the orthogonal ones — a live demonstration that the tessellation really is metric and square.

Notes for integrators

  • Everything is WGS84 on the way in. Coordinates from Survey of India toposheets are on the Everest 1830 datum and differ by 200–300 m in this region. Datum- shift before you encode — see accuracy.
  • Truncate, don’t round. To disclose a coarser position, drop trailing words rather than reducing coordinate precision. A prefix is a real address for a real, larger cell; a rounded coordinate is a point that may sit in a different cell entirely.
  • Cache freely. Responses are pure functions of their inputs and will never change for a given lexicon version. They are served with a one-year immutable cache header.
  • Coverage is finite. A 50 km × 60 km extent over the Chennai Metropolitan Area. Anything outside it is an error, deliberately, rather than a wrapped-around address.

Doing it without the network

The whole model — projection, tessellation, lexicon — is about 70 KB of committed JSON and a few hundred lines of arithmetic. For an offline or embedded client, porting it is strictly easier than calling this API, and the method page specifies it completely.