StudyMap

Docs/Places API

Places API

Read the crowdsourced places dataset programmatically: GET /api/places, filters, pagination, and errors.

StudentSuite Team · · 3 min read

Every place StudyMap renders is crowdsourced and committed to data/places/*.json — one file per category. The API below exposes that dataset read-only, so anything can be built on top of it without cloning the repo.

GET /api/places
The merged dataset, optionally filtered, with bounded pagination.
# Everything (paginated at 100 rows)
curl "https://studyymap.com/api/places"

# A city filter - "New Delhi" and "new_delhi" both work
curl "https://studyymap.com/api/places?city=mumbai&limit=5"

# Category + pagination
curl "https://studyymap.com/api/places?category=library&limit=50&offset=100"

Responses are plain JSON with permissive CORS (Access-Control-Allow-Origin: *), so browser code can call it directly. Responses are cached for 6 hours (the dataset changes a few times a week at most) via Cache-Control headers.

Query parameters
All optional; every value is validated, and invalid values are a 400 with a message - never silently ignored.
  • city (string)

    Case-insensitive; spaces and hyphens are normalized to the dataset's underscore slugs (e.g. `New Delhi` matches `new delhi`). No matching city returns an empty `data` array.

  • category (enum)

    One of `library`, `other_places`, `airport`, `sat_centre`, `foreign_lang_exam_centre`, `gov_offices`. Anything else is a 400.

  • country (string)

    Rejected with a 400 today: the dataset schema has no `country` field yet, so no record could satisfy the filter.

  • limit (positive integer)

    Default 100; values above the hard maximum of 500 are clamped, never dumped.

  • offset (non-negative integer)

    Zero-based. Combine with `limit` to page through large results.

Response shape
Each record is exactly one entry from data/places/*.json, as defined by the schema.
{
  "data": [
    {
      "id": "mum-library-01",
      "name": "David Sassoon Library",
      "type": "library",
      "city": "mumbai",
      "lat": 18.9674,
      "lng": 72.8339,
      "address": "Fort, Mumbai 400001",
      "gmaps_link": "https://maps.google.com/?q=18.9674,72.8339",
      "added_by": "thunderblitzyt-eng"
    }
  ],
  "total": 1,
  "limit": 100,
  "offset": 0
}

total is the number of matches before pagination, so consumers know the full result set size. The canonical record shape lives in data/places.schema.json.

Errors
Invalid filter values return 400 with an error message instead of being ignored.
{
  "error": "unknown category \"bookshop\"; expected one of library, other_places, airport, sat_centre, foreign_lang_exam_centre, gov_offices"
}

400 cases: an unknown category, country (no country data in the schema yet), a non-integer limit or offset, or a repeated parameter. A city with no places is an empty result, not an error.

No API key, no write access
This endpoint is read-only and deliberately unauthenticated - the dataset is public by design. To add or correct a place, open a pull request against data/places/*.json following the contributing guide.

Ready to use what you just read?