6°12'S 106°49'E GRID REF 48M

Every place,
indexed.

Automated POI scraping pipeline that discovers, extracts, normalizes, and serves point-of-interest data through a spatial search API. From raw web data to structured, queryable geography.

api/v1/pois/nearby
// Spatial search — find cafes within 2km
$ GET /api/v1/pois/nearby?lat=-6.2&lon=106.8&radius=2000&category=cafe
 
{
  "data": [{
    "name": "Kopi Brumbun",
    "distance_m": 342,
    "rating": 4.6,
    "coordinates": [-6.201, 106.812],
    "hours": { "monday": "07:00–17:00" },
    "categories": ["cafe", "coffee-shop"]
  }],
  "coverage": true
}
12,536
Points of Interest
337
Categories
50m
Dedup Radius
v1
API Version

From search to
structured data

A four-stage queue-based pipeline that scrapes, extracts, normalizes, and deduplicates POI data — fully automated, with AI-assisted categorization.

01
Scrape
Headless browser navigates map listings, scrolling and extracting raw detail pages at scale.
Node.js + Playwright
02
Extract
AI normalizes categories and operating hours across languages. Structured fields copied directly.
Gemini 2.5 Flash
03
Normalize
Deduplication by place ID, then proximity + fuzzy name matching. Categories mapped through alias chains.
PostGIS + 50m radius
04
Serve
Spatial search API with radius queries, category filters, and structured POI responses with hours and images.
REST API v1

Built for precision

Every component designed for data quality, from scraping resilience to spatial accuracy.

Spatial Search
PostGIS-powered radius queries with sub-meter precision. Find POIs within any distance from any coordinate on Earth.
Smart Dedup
Three-layer deduplication: exact Place ID match, 50-meter proximity check, then 70% fuzzy name similarity scoring.
Operating Hours
AI-normalized hours across languages and formats. Indonesian, English, abbreviated — parsed into structured time fields.
Category Mapping
Indonesian alias chains map local terms to canonical categories. "Kedai kopi" resolves to "cafe" automatically.
Admin Panel
Full Filament dashboard with map view, duplicate resolution, scrape monitoring, and on-demand image fetching.
Queue Pipeline
Three dedicated workers with independent timeouts. Long scrapes don't block AI extraction or normalization.

Spatial queries,
structured responses

RESTful API with token authentication, spatial search, category filtering, and GeoJSON export.

  • GET /api/v1/pois/nearby Spatial search
  • GET /api/v1/pois/{id} POI detail
  • GET /api/v1/pois/export GeoJSON export
  • GET /api/v1/categories All categories

Query Parameters

lat, lon Search center coordinates radius Search radius in meters (max 50km) category Filter by category slug keyword Search by POI name limit Results per page (max 100)
Response — POI Detail 200 OK
{ "data": { "id": 42, "name": "BENING Coffee & Space", "address": "Jl. Raya Juanda No.12", "phone": "+62 812-3456-7890", "coordinates": { "lat": -7.3813, "lon": 112.7772 }, "rating": 4.5, "review_count": 238, "categories": [ "cafe", "coworking" ], "hours": [ { "day": "monday", "opens": "09:00", "closes": "22:00" }, // ... 6 more days ], "images": [ "https://..." ], "completeness": 85 } }
Start exploring

Get an API token from the admin panel and start querying spatial data.