The same JSON the Streetside front-end consumes is yours to consume too. There is no API key, no signup, no quota dashboard, no OAuth dance — just two endpoints that return the camera catalogue and per-camera detail. The data is edge-cached for sixty seconds at our Cloudflare boundary, so even an inefficient client will not meaningfully tax the upstream. Two requests, please: rate-limit yourself to roughly one request per second, and if you publish anything built on this data, attribute back to Streetside Jakarta with a link. That is the entire contract. Build a dashboard, a Telegram bot, a research notebook, a screensaver — whatever pleases you. The endpoints are documented below in the order you will probably need them.
GET /api/cameras
Request
GET /api/cameras
Accept: application/json Returns the full active camera catalogue as a JSON array under the cameras key. Cameras without coordinates and disabled cameras are filtered out at the edge before you ever see them. Field shapes mirror the upstream Molecool API verbatim, with the exception of latitude and longitude which may arrive as either numbers or numeric strings — coerce defensively.
Response shape
{
"cameras": [
{
"id": 1234,
"cctv_name": "Bundaran HI",
"city_name": "Jakarta Pusat",
"district_name": "Menteng",
"subdistrict_name": "Gondangdia",
"latitude": -6.1944,
"longitude": 106.8229,
"address": "Jl. M.H. Thamrin, Bundaran HI"
}
]
} The response carries Cache-Control: public, max-age=60 and an X-Cache header of either KV-HIT or MISS. The catalogue refresh cadence is sixty seconds; polling more often than that will simply hit the same cached payload.
GET /api/cameras/[id]
Request
GET /api/cameras/1234
Accept: application/json Returns the detail record for a single camera, including the live HLS playlist URL and the most recent still image. The id URL parameter is a string in the path but corresponds to the numeric id field from the list endpoint. Unknown ids return 404; upstream failures return 502.
Response shape
{
"camera": {
"id": 1234,
"cctv_name": "Bundaran HI",
"city_name": "Jakarta Pusat",
"district_name": "Menteng",
"subdistrict_name": "Gondangdia",
"latitude": -6.1944,
"longitude": 106.8229,
"address": "Jl. M.H. Thamrin, Bundaran HI",
"image1": "https://.../snapshot.jpg",
"hls": "https://.../stream.m3u8",
"description": "Traffic camera at Bundaran HI roundabout."
}
} Detail responses are also cached for sixty seconds at the edge. Note that image1 is a short-lived signed URL from the upstream — typically valid for about an hour — so do not bookmark it. The hls URL points at our /stream/[...path] proxy and stays valid as long as the camera remains in the index.
Terms
- Free for non-commercial use. Commercial use requires a quick email first.
- Attribute as "Streetside Jakarta" with a link back to streetside.mugnimaestra.dev.
- Don't hammer the endpoints — at least one second between requests is plenty, and the catalogue itself only changes every sixty seconds.
- Underlying CCTV feeds are sourced from the DKI Jakarta provincial government. See data sources for the full provenance, refresh cadence, and licence.