Other data: Transjakarta and points of interest
Documentation index for AI agents: /llms.txt. Every page is also available as markdown: add
.mdto the URL.
Transjakarta GTFS routes, stops, fares and schedules, plus points of interest in Indonesia.
Transjakarta data comes from the official PT Transportasi Jakarta GTFS feed. Points of interest can be listed, filtered by category or searched near a coordinate.
All endpoints need the x-api-key header (see Authentication) and return the standard envelope. A successful request costs 2 credits.
Endpoints on this page
GET /api/v1/transjakarta/rute: List routesGET /api/v1/transjakarta/rute/{id}: Retrieve a routeGET /api/v1/transjakarta/halte: List halteGET /api/v1/transjakarta/halte/nearby: Nearest halteGET /api/v1/transjakarta/halte/{id}: Retrieve a halteGET /api/v1/transjakarta/tarif: List faresGET /api/v1/transjakarta/jadwal: Departure headwaysGET /api/v1/poi: Search & list POIGET /api/v1/poi/nearby: Nearest POIGET /api/v1/poi/categories: List categoriesGET /api/v1/poi/{id}: Retrieve a POI
Transjakarta (Official PT Transportasi Jakarta GTFS)
Transjakarta bus routes with the halte they serve, fares, and departure headways.
- Bus routes with the halte they serve
- Nearest-halte search from a coordinate
- Fares
- Per-route departure headways
- Data: the official static GTFS published by PT Transportasi Jakarta, licensed CC BY 4.0, reusable commercially as long as the attribution is kept
GET /api/v1/transjakarta/rute
List routes. Returns the 240 Transjakarta routes.
- Short and long names
- Service description (BRT, integrated public transport, Mikrotrans, Transjabodetabek, tour bus)
- GTFS route type
- Corporate colour with its text colour
- The number of unique halte the route serves, counted across both directions, not the number of rows
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
q | query | no | string | Partial, case-insensitive route-name search, e.g. blok (23 routes). |
page | query | no | integer | Page to retrieve. Defaults to 1; a page past the offset ceiling answers 400 PAGINATION_LIMIT. |
per_page | query | no | integer | Items per page. Defaults to 20, maximum 100. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/rute" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "1",
"short_name": "1",
"long_name": "Blok M - Kota",
"description": "BRT",
"route_type": 3,
"color": "D62126",
"text_color": "FFFFFF",
"jumlah_halte": 59
},
{
"id": "1C",
"short_name": "1C",
"long_name": "Pesanggrahan - Blok M",
"description": "Angkutan Umum Integrasi",
"route_type": 3,
"color": "D65E62",
"text_color": "000000",
"jumlah_halte": 76
}
],
"meta": {
"total": 23,
"page": 1,
"per_page": 2,
"total_pages": 12,
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/rute/{id}
Retrieve a route. One route in full.
- The fares that apply to it (from fare_rules)
- Its departure headways (per trip)
- The halte list of both directions: "ke" for direction_id 0 and "kembali" for direction_id 1, each ordered by ascending stop_sequence
- An unknown route answers 404 NOT_FOUND
- The official release carries no street geometry, so per-segment travel distances are not available here
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
id | path | yes | string | Route ID, e.g. 1, 1C, 10A, or JAK.79. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/rute/1" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": {
"id": "1",
"short_name": "1",
"long_name": "Blok M - Kota",
"description": "BRT",
"route_type": 3,
"color": "D62126",
"text_color": "FFFFFF",
"tarif": [
{
"id": "FP",
"price": 3500,
"currency": "IDR"
}
],
"frekuensi": [
{
"trip_id": "1-P23",
"start_time": "00:00:00",
"end_time": "23:59:59",
"headway_secs": 900
},
{
"trip_id": "1-P28",
"start_time": "00:00:00",
"end_time": "23:59:59",
"headway_secs": 900
}
],
"halte": {
"ke": [
{
"stop_id": "P00017",
"name": "Blok M",
"lat": -6.243312,
"lng": 106.80175,
"stop_sequence": 0
},
{
"stop_id": "G00012",
"name": "Asean",
"lat": -6.239911,
"lng": 106.79897,
"stop_sequence": 1
}
],
"kembali": [
{
"stop_id": "G00060",
"name": "Kali Besar",
"lat": -6.135355,
"lng": 106.81143,
"stop_sequence": 0
},
{
"stop_id": "G00064",
"name": "Museum Sejarah Jakarta",
"lat": -6.133882,
"lng": 106.81214,
"stop_sequence": 1
}
]
}
},
"meta": {
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/halte
List halte. Returns the 8,091 Transjakarta halte with code, name, coordinates, and GTFS stop type. The q filter partially matches name, code, or halte ID.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
q | query | no | string | Search a halte by name, code, or ID, e.g. monas or B02475P. |
page | query | no | integer | Page to retrieve. Defaults to 1. |
per_page | query | no | integer | Items per page. Defaults to 20, maximum 100. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/halte" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "B02475P",
"code": null,
"name": "Monas 1",
"lat": -6.172531,
"lng": 106.82315,
"stop_type": 0
},
{
"id": "B02476P",
"code": null,
"name": "Monas 2",
"lat": -6.175999,
"lng": 106.82311,
"stop_type": 0
}
],
"meta": {
"total": 3,
"page": 1,
"per_page": 3,
"total_pages": 1,
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/halte/nearby
Nearest halte. Finds the halte around a coordinate, nearest first, with the distance in metres (distance_m).
- A bounding box is applied first and the exact great-circle distance second, so a 5 km radius stays cheap
- Radius defaults to 1,000 metres (maximum 5,000) and limit to 20 (maximum 100)
- A missing or non-numeric lat/lng, a radius outside 1-5,000, or a limit outside 1-100 answers 400 VALIDATION_ERROR
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
lat | query | yes | number | Latitude of the reference point, -90 to 90, e.g. -6.172531. |
lng | query | yes | number | Longitude of the reference point, -180 to 180, e.g. 106.82315. |
radius | query | no | integer | Search radius in metres, 1 to 5,000. Defaults to 1,000. |
limit | query | no | integer | Maximum halte returned, 1 to 100. Defaults to 20. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/halte/nearby?lat=-6.172531&lng=106.82315" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "B02475P",
"code": null,
"name": "Monas 1",
"lat": -6.172531,
"lng": 106.82315,
"stop_type": 0,
"distance_m": 0
},
{
"id": "B01649P",
"code": null,
"name": "Jln. Tanah Abang I",
"lat": -6.173433,
"lng": 106.8214,
"stop_type": 0,
"distance_m": 218
}
],
"meta": {
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/halte/{id}
Retrieve a halte. One halte plus the routes that call there, one row per route and direction pair (direction_id). A halte served in both directions appears twice, and a tourist halte can be served by several routes. An unknown halte answers 404 NOT_FOUND.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
id | path | yes | string | Halte ID, e.g. B02475P. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/halte/B02475P" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": {
"id": "B02475P",
"code": null,
"name": "Monas 1",
"lat": -6.172531,
"lng": 106.82315,
"stop_type": 0,
"rute": [
{
"route_id": "BW2",
"short_name": "BW2",
"long_name": "Monas Explorer",
"direction_id": 0
},
{
"route_id": "BW4",
"short_name": "BW4",
"long_name": "Pencakar Langit",
"direction_id": 0
}
]
},
"meta": {
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/tarif
List fares. The six GTFS fares with their rupiah prices.
- FP: Rp3,500, the flat Transjakarta fare
- GR: Rp0, free on selected routes
- PP: Rp20,000, plus PP2/PP3 for airport services
- How many transfers are allowed (null means the fare covers a single journey)
- This endpoint does not paginate, so meta carries the attribution only
curl "https://use.apiindonesia.id/api/v1/transjakarta/tarif" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "GR",
"price": 0,
"currency": "IDR",
"payment_method": 0,
"transfers": null,
"transfer_duration": 10800
},
{
"id": "FP",
"price": 3500,
"currency": "IDR",
"payment_method": 0,
"transfers": null,
"transfer_duration": 10800
}
],
"meta": {
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
GET /api/v1/transjakarta/jadwal
Departure headways. Departure frequencies from GTFS frequencies.txt.
- One row per trip serving that route, with the operating window and the headway in seconds (900 seconds means a bus every 15 minutes)
- The route filter narrows the result to one route; a route without frequency rows answers an empty list, not a 404
- Times are returned as the source "HH:MM:SS" strings, so night services can exceed 24:00:00
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
rute | query | no | string | Route ID to narrow the result, e.g. 10A. |
page | query | no | integer | Page to retrieve. Defaults to 1. |
per_page | query | no | integer | Items per page. Defaults to 20, maximum 100. |
curl "https://use.apiindonesia.id/api/v1/transjakarta/jadwal" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"trip_id": "10A-L02",
"route_id": "10A",
"start_time": "05:00:00",
"end_time": "22:00:00",
"headway_secs": 2180,
"exact_times": 0
},
{
"trip_id": "10A-R01",
"route_id": "10A",
"start_time": "05:00:00",
"end_time": "22:00:00",
"headway_secs": 1200,
"exact_times": 0
}
],
"meta": {
"total": 2,
"page": 1,
"per_page": 20,
"total_pages": 1,
"attribution": {
"source": "PT Transportasi Jakarta (Transjakarta) GTFS",
"license": "CC BY 4.0",
"license_url": "https://creativecommons.org/licenses/by/4.0/",
"source_url": "https://gtfs.transjakarta.co.id/files/file_gtfs.zip",
"attribution_page": "https://ppid.transjakarta.co.id/informasi/berkala",
"notice": "Data diubah: dinormalisasi ke format JSON API Indonesia"
}
}
}
Indonesia POI (Overture Maps Places)
Location category: 1,376,228 places (POI) in Indonesia from the Overture Maps Foundation Places theme, release 2026-10-21.0.
- From restaurants, mosques, schools, government offices and hotels to shops, across 1,250 categories
- Search by name prefix, category or city (locality)
- Find the POI nearest to a coordinate
- Fetch one POI in detail
- Only places with an Overture confidence score of at least 0.5 are included, and every POI carries its score (0 to 1)
- Only the Places theme is used (CDLA Permissive 2.0 and Apache 2.0), with no OpenStreetMap data
GET /api/v1/poi
Search & list POI. POI list ordered by name.
- The q filter matches the START of the name, case-insensitively (q=masjid matches "Masjid Istiqlal", q=istiqlal does not)
- category takes a key from /api/v1/poi/categories
- locality (alias kota) matches the city/regency exactly as written in the Overture address, e.g. "Jakarta Selatan" or "Surabaya"
- Filters can be combined
- per_page is capped at 100 and the offset at 5,000
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
q | query | no | string | Name prefix, e.g. monumen. |
category | query | no | string | Overture category key, e.g. muslim_place_of_worship. |
locality | query | no | string | City/regency as in the Overture address (alias: kota), e.g. Jakarta Pusat. |
page | query | no | integer | Page to retrieve. Defaults to 1. |
per_page | query | no | integer | Items per page. Defaults to 20, maximum 100. |
curl "https://use.apiindonesia.id/api/v1/poi" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "58fef60b-6916-4905-a28b-9dec369147f1",
"name": "Monumen Nasional",
"category": "monument",
"basic_category": "monument",
"category_hierarchy": [
"cultural_and_historic",
"memorial_site"
],
"alternate_categories": [],
"confidence": 0.9699,
"lat": -6.1753244,
"lon": 106.8271812,
"address": {
"freeform": "Jalan Medan Merdeka",
"locality": "Jakarta Pusat",
"region": null,
"postcode": "10310",
"country": "ID"
},
"websites": [
"http://en.wikipedia.org/wiki/National_Monument_(Indonesia)"
],
"phones": [
"+62213823041"
],
"brand": null,
"operating_status": null,
"sources": [
{
"dataset": "meta",
"license": "CDLA-Permissive-2.0"
}
]
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 1,
"total_pages": 1,
"attribution": {
"source": "Overture Maps Foundation, Places theme (overturemaps.org)",
"license": "CDLA-Permissive-2.0 dan Apache-2.0 (rekaman Foursquare); CC0-1.0 (rekaman AllThePlaces)",
"license_url": "https://cdla.dev/permissive-2-0/",
"source_url": "https://docs.overturemaps.org/guides/places/",
"attribution_page": "https://docs.overturemaps.org/attribution/",
"notice": "Data diubah oleh API Indonesia: ...",
"release": "2026-10-21.0",
"licenses": [
{
"name": "CDLA-Permissive-2.0",
"url": "https://cdla.dev/permissive-2-0/",
"applies_to": "..."
},
{
"name": "Apache-2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0",
"applies_to": "rekaman bersumber Foursquare"
}
],
"third_party_notices": [
"Data from Foursquare. Copyright 2024 Foursquare Labs, Inc. ...",
"© 2026 Foursquare Labs, Inc. All rights reserved. ..."
]
}
}
}
GET /api/v1/poi/nearby
Nearest POI. POI around a coordinate, nearest first, with the distance in metres (distance_m).
- Optionally filtered by category and minimum confidence (min_confidence)
- Radius defaults to 1,000 metres (maximum 5,000) and limit to 20 (maximum 100)
- A missing or non-numeric lat/lon, a radius outside 1-5,000, a limit outside 1-100, or a min_confidence outside 0-1 answers 400 VALIDATION_ERROR
- lng is accepted as an alias for lon
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
lat | query | yes | number | Latitude of the reference point, e.g. -6.1753924. |
lon | query | yes | number | Longitude of the reference point, e.g. 106.8271528. |
radius | query | no | integer | Radius in metres, 1 to 5,000. Defaults to 1,000. |
category | query | no | string | Category key, e.g. cafe. |
min_confidence | query | no | number | Minimum Overture confidence, 0 to 1, e.g. 0.9. |
limit | query | no | integer | Maximum POI returned, 1 to 100. Defaults to 20. |
curl "https://use.apiindonesia.id/api/v1/poi/nearby?lat=-6.1753924&lon=106.8271528" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"id": "58fef60b-6916-4905-a28b-9dec369147f1",
"name": "Monumen Nasional",
"category": "monument",
"confidence": 0.9699,
"lat": -6.1753244,
"lon": 106.8271812,
"...": "...",
"distance_m": 8
}
],
"meta": {
"attribution": {
"source": "Overture Maps Foundation, Places theme (overturemaps.org)",
"...": "..."
}
}
}
GET /api/v1/poi/categories
List categories. Every Overture category present in the Indonesian data (1,250 categories), most POI first, with basic_category, taxonomy hierarchy and POI count. The q filter partially matches the category key.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
q | query | no | string | Part of the category key, e.g. restaurant. |
curl "https://use.apiindonesia.id/api/v1/poi/categories" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": [
{
"category": "muslim_place_of_worship",
"basic_category": "muslim_place_of_worship",
"hierarchy": [
"cultural_and_historic",
"place_of_worship"
],
"total": 55014
}
],
"meta": {
"attribution": {
"source": "Overture Maps Foundation, Places theme (overturemaps.org)",
"...": "..."
}
}
}
GET /api/v1/poi/{id}
Retrieve a POI. One POI by its Overture ID (GERS ID, stable across releases). An unknown ID answers 404 NOT_FOUND.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
id | path | yes | string | Overture ID, e.g. 58fef60b-6916-4905-a28b-9dec369147f1. |
curl "https://use.apiindonesia.id/api/v1/poi/58fef60b-6916-4905-a28b-9dec369147f1" \
-H "x-api-key: YOUR_API_KEY"
Example response (shortened):
{
"success": true,
"data": {
"id": "58fef60b-6916-4905-a28b-9dec369147f1",
"name": "Monumen Nasional",
"category": "monument",
"...": "..."
},
"meta": {
"attribution": {
"source": "Overture Maps Foundation, Places theme (overturemaps.org)",
"...": "..."
}
}
}