> ## Documentation Index
> Fetch the complete documentation index at: https://docs.baato.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Core concepts

> The handful of Baato conventions worth knowing before you write integration code.

Baato's endpoints are small and consistent, but a few conventions trip people up on the
first integration. This page covers all of them.

## The response envelope

Every endpoint except [Map Styles](/services/styles) returns the same wrapper. The payload
you want is always under `data`.

```json theme={null}
{
  "timestamp": "Thu May 14 07:35:16 NPT 2020",
  "status": 200,
  "message": "Success",
  "data": []
}
```

<ResponseField name="timestamp" type="string">
  Server time when the response was generated, in Nepal Time.
</ResponseField>

<ResponseField name="status" type="integer">
  The HTTP status, echoed into the body. It matches the real HTTP status code — check the
  transport-level status, not this field, when handling errors.
</ResponseField>

<ResponseField name="message" type="string">
  `Success` on a 2xx, or a human-readable explanation otherwise.
</ResponseField>

<ResponseField name="data" type="array">
  The results. Always an array, even for endpoints that return a single logical result —
  [Places](/services/places) and [Reverse Search](/services/reverse) both return a
  one-element array, so read `data[0]`.
</ResponseField>

[Map Styles](/services/styles) is the exception: it returns a raw
[Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/) document
with no envelope, because map renderers consume it directly.

## Coordinate order

<Warning>
  Baato takes latitude and longitude as **separate `lat` and `lon` parameters**, and
  [Directions](/services/directions) takes points as `"lat,lon"` strings. GeoJSON, MapLibre
  GL and Mapbox GL all take `[lon, lat]` arrays. Reversing them silently places your map in
  the wrong hemisphere rather than throwing an error.
</Warning>

Kathmandu is at latitude `27.7172`, longitude `85.3240`. The same point, three ways:

```javascript theme={null}
// Baato request parameters — named, order does not matter
{ lat: 27.7172, lon: 85.3240 }

// Baato Directions points[] — "lat,lon"
"27.7172,85.3240"

// MapLibre / Mapbox / GeoJSON — [lon, lat]
[85.3240, 27.7172]
```

Baato responses use named fields (`centroid.lat`, `centroid.lon`), so the risk is in the
handoff to your map library:

```javascript theme={null}
const place = response.data[0];

// Correct — swap into [lon, lat] for the renderer
new maplibregl.Marker()
  .setLngLat([place.centroid.lon, place.centroid.lat])
  .addTo(map);
```

The one place Baato *does* emit renderer-order coordinates is the `geometry` field on a
[Place](/services/places), which is GeoJSON and therefore already `[lon, lat]`.

## Identifying a place

<Expandable title="placeId, osmId and how they differ" defaultOpen>
  <ResponseField name="placeId" type="integer">
    Baato's own identifier. Returned by [Search](/services/search),
    [Places](/services/places), [Reverse Search](/services/reverse) and
    [Nearby Places](/services/nearby-places). This is the ID you pass back to the Places API.
  </ResponseField>

  <ResponseField name="osmId" type="integer">
    The underlying OpenStreetMap object ID, returned only by
    [Nearby Places](/services/nearby-places). Useful for cross-referencing against OSM, not
    for querying Baato.
  </ResponseField>
</Expandable>

The two-step search flow exists because search responses are optimised for autocomplete
UIs — they omit geometry to stay small and fast:

<Steps>
  <Step title="Search returns lightweight suggestions">
    `GET /search?q=patan` → name, address, type, `placeId`. No coordinates.
  </Step>

  <Step title="Places resolves one suggestion in full">
    `GET /places?placeId=344470` → centroid, geometry and OpenStreetMap tags.
  </Step>
</Steps>

Call step two only when the user picks a result, not for every keystroke.

## Encoded polylines

[Directions](/services/directions) returns route geometry as `encodedPolyline` — a compact
string in [Google's encoded polyline format](https://developers.google.com/maps/documentation/utilities/polylinealgorithm),
rather than a large GeoJSON `LineString`. Decode it before handing it to a renderer.

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Baato.Routing() decodes for you — each result carries a ready-made .geojson
  new Baato.Routing({ key: "YOUR_BAATO_ACCESS_TOKEN" })
    .addPoints(["27.6950,85.3078", "27.7067,85.3337"])
    .setVehicle("foot")
    .getBest()
    .doRequest()
    .then((routes) => {
      map.getSource("route").setData({
        type: "Feature",
        geometry: { type: "LineString", coordinates: routes[0].geojson.coordinates },
      });
    });
  ```

  ```javascript React Native theme={null}
  import polyline from "@mapbox/polyline";

  const geojson = polyline.toGeoJSON(route.encodedPolyline);
  ```

  ```dart Flutter theme={null}
  // The Flutter client decodes for you
  final route = await Baato.api.direction.getRoutes(
    startCoordinate: start,
    endCoordinate: end,
    mode: BaatoDirectionMode.car,
    decodePolyline: true,
  );
  ```
</CodeGroup>

Alongside the geometry, every route carries `distanceInMeters`, `timeInMs` (milliseconds,
not seconds) and — when you request `instructions=true` — an `instructionList`. Without that
parameter, `instructionList` is `null` rather than an empty array.

## Place types

The `type` field is drawn from
[OpenStreetMap map features](https://wiki.openstreetmap.org/wiki/Map_features). Baato also
defines a few merged types that combine related features, so `type=eat` returns cafes,
restaurants and bakeries together. The full list is on the
[Nearby Places](/services/nearby-places#supported-place-types) page.

## Relevance scores

Search and Places results carry a `score`. Higher is more relevant, but the scale is not
normalised — compare scores within a single response, never across responses.

<Note>
  Endpoints that do not compute a score return the **string** `"NaN"` rather than a number
  or `null`. Guard against it before doing arithmetic:

  ```javascript theme={null}
  const score = typeof result.score === "number" ? result.score : 0;
  ```
</Note>

## Versioning

All endpoints live under `https://api.baato.io/api/v1`. See
[API versioning](/about/api-versioning) for how new versions are introduced.
