Tutorial Cara Ambil Data Resmi BPS Pakai API (Lengkap dengan Contoh Live)
Syafriadi 8 November 2026 ⏱ 8 menit baca
Ambil data resmi BPS lewat API sebenarnya selesai dalam satu request HTTP. Endpoint https://webapi.bps.go.id/v1/api/list/model/data/lang/ind/domain/0000/var/184/th/124;125/key/<API_KEY>/ menjawab 200 OK dengan 1.104 byte JSON berisi 12 sel angka kemiskinan nasional untuk 2024 dan 2025, dan itu terukur langsung dari server BPS pada 8 November 2026. Yang bikin orang menyerah bukan endpoint-nya, tapi dua hal: kode th yang harus dicari manual, dan datacontent yang kuncinya komposit. Artikel ini membongkar keduanya pakai angka nyata dari respons API, bukan contoh karangan.
TL;DR
- Endpoint data:
/v1/api/list/model/data/lang/ind/domain/0000/var/<var>/th/<th>/key/<API_KEY>/
- Kode
th 123 = 2023, 124 = 2024, 125 = 2025; turtahun 61 = Semester 1 (Maret), 62 = Semester 2 (September)
datacontent berkunci komposit: vervar + var + th + turtahun, contoh 3184012461 = 9,03 persen
- Tanpa key, API menjawab HTTP 400 dengan pesan
Missing required parameter: key.
- Kemiskinan nasional September 2025 tercatat 8,25 persen menurut data yang ditarik dari API pada 8 November 2026
Apa yang sebenarnya dikirim API BPS?
API BPS mengirim satu objek JSON berisi metadata variabel plus satu kamus angka, dan hampir semua kebingungan muncul karena orang membaca kamus itu sebelum membaca metadatanya. Respons untuk variabel 184 (Persentase Penduduk Miskin) punya 12 kunci di datacontent, 2 entri di tahun, 3 entri di turtahun, dan 3 entri di vervar. Angka tidak pernah dikirim sebagai baris tabel siap pakai. Angka dikirim sebagai nilai yang ditempel pada kunci hasil gabungan beberapa dimensi, jadi langkah pertama selalu menerjemahkan kunci, bukan menjumlahkan nilai.
Isi responsnya bisa dipetakan seperti ini.
| Field |
Isi |
Contoh dari respons nyata |
status |
Status permintaan |
OK |
var |
Metadata variabel yang diminta |
var 184, label "Persentase Penduduk Miskin (P0) Menurut Daerah" |
vervar |
Dimensi wilayah atau kategori |
1 = Kota, 2 = Desa, 3 = Kota+Desa |
tahun |
Daftar tahun beserta kodenya |
124 = 2024, 125 = 2025 |
turtahun |
Periode dalam tahun |
61 = Semester 1 (Maret), 62 = Semester 2 (September), 63 = Tahunan |
datacontent |
Kamus angka, kunci komposit |
3184012562 = 8,25 |
last_update |
Stempel pembaruan data di sisi BPS |
ikut dikirim di setiap respons |
Struktur ini konsisten di semua model data. Kalau lo paham satu respons, lo paham respons berikutnya. Yang berubah cuma jumlah kunci dan labelnya.
Bagaimana cara memanggil API BPS dari Python?
Panggil dengan urllib bawaan Python, simpan API key di file terpisah, lalu baca JSON-nya sebagai kamus. Tidak perlu library tambahan, tidak perlu browser. Kode di bawah ini persis pola yang dipakai pipeline data harian dan sudah dijalankan terhadap server BPS, jadi hasilnya bukan teoretis.
```python
import json, os, re, urllib.request
KEY = re.search(r'API_KEY\s=\s"([^"]+)"', open(os.path.expanduser("~/bps_key.py")).read()).group(1)
UA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36"
def bps(var, th):
url = ("https://webapi.bps.go.id/v1/api/list/model/data/lang/ind/"
f"domain/0000/var/{var}/th/{th}/key/{KEY}/")
req = urllib.request.Request(url, headers={"User-Agent": UA})
with urllib.request.urlopen(req, timeout=25) as r:
return json.load(r)
d = bps("184", "124;125")
print(d["status"], len(d["datacontent"]))
```
Tiga hal yang perlu diperhatikan dari potongan di atas. Pertama, parameter th menerima beberapa tahun sekaligus dengan pemisah titik koma, jadi 124;125 mengambil 2024 dan 2025 dalam satu request. Kedua, domain/0000 berarti level nasional, dan kode domain provinsi dipakai kalau lo mau angka per provinsi. Ketiga, User-Agent dikirim eksplisit. Pada pengujian 8 November 2026 endpoint data masih menjawab 200 walau User-Agent kosong, tapi endpoint lain di domain yang sama berada di belakang WAF, jadi jangan menjadikan kebiasaan tanpa header sebagai patokan.
Bagaimana membaca datacontent yang kuncinya komposit?
Kunci datacontent adalah gabungan empat bagian: kode vervar, kode var, kode tahun, dan kode turunan tahun, tanpa pemisah. Ambil contoh 3184012461. Potongannya 3 untuk vervar (Kota+Desa), 184 untuk var, 124 untuk tahun 2024, dan 61 untuk Semester 1. Nilainya 9,03, yang berarti 9,03 persen penduduk miskin di kota dan desa pada Maret 2024. Karena tidak ada pemisah, satu-satunya cara memotongnya adalah dengan mengetahui panjang tiap bagian, dan panjang itu ditentukan oleh kode var yang lo minta.
| Kunci |
Vervar |
Var |
Tahun |
Turtahun |
Nilai |
3184012461 |
3 (Kota+Desa) |
184 |
124 (2024) |
61 (Maret) |
9,03 |
3184012462 |
3 (Kota+Desa) |
184 |
124 (2024) |
62 (September) |
8,57 |
3184012561 |
3 (Kota+Desa) |
184 |
125 (2025) |
61 (Maret) |
8,47 |
3184012562 |
3 (Kota+Desa) |
184 |
125 (2025) |
62 (September) |
8,25 |
828401230 |
8 (USD) |
284 |
123 (2023) |
0 (Tahun) |
15.416 |
828401240 |
8 (USD) |
284 |
124 (2024) |
0 (Tahun) |
16.162 |
Perhatikan baris terakhir: var 284 (Kurs Tengah Beberapa Mata Uang Asing Terhadap Rupiah) memakai turtahun 0 dengan label "Tahun", jadi kuncinya lebih pendek satu digit dibanding var 184. Inilah sebabnya regex yang dipakai untuk memotong kunci harus ditulis per variabel, bukan satu pola generik untuk semua. Pola ^31840(12[45])(\d{2})$ hanya valid untuk var 184 dengan vervar 3, dan pola ^82840(12[34])(\d{1,2})$ hanya valid untuk var 284 dengan vervar 8.
Angka apa saja yang bisa diambil sebagai contoh?
Dua variabel yang paling sering dipakai untuk latihan adalah kemiskinan (var 184) dan kurs tengah Bank Indonesia (var 284), karena keduanya nasional, rilisnya rutin, dan tidak butuh kode wilayah. Dari satu snapshot API pada 8 November 2026, keduanya memberi enam angka yang bisa langsung dipakai sebagai pembanding di laporan atau dashboard.
| Indikator |
Periode |
Nilai |
Satuan |
Var |
| Penduduk miskin nasional |
Maret 2024 |
9,03 |
persen |
184 |
| Penduduk miskin nasional |
September 2024 |
8,57 |
persen |
184 |
| Penduduk miskin nasional |
Maret 2025 |
8,47 |
persen |
184 |
| Penduduk miskin nasional |
September 2025 |
8,25 |
persen |
184 |
| Kurs tengah BI, USD |
Rata-rata 2023 |
15.416 |
rupiah |
284 |
| Kurs tengah BI, USD |
Rata-rata 2024 |
16.162 |
rupiah |
284 |
Kalau dihitung dari tabel di atas, kemiskinan turun 0,78 poin persen dari Maret 2024 ke September 2025, dan penurunannya konsisten di setiap semester. Kurs bergerak ke arah sebaliknya: rata-rata 2024 lebih tinggi 746 rupiah dibanding 2023, atau sekitar 4,8 persen. Dua arah yang berlawanan ini penting disebut karena orang sering mengutip salah satunya saja. Sumber angkanya BPS lewat API, ditarik 8 November 2026, dan periode acuannya tertulis di kolom tabel, bukan "terbaru".
Yang perlu dicatat: tahun 125 hanya tersedia untuk var 184, sementara var 284 pada permintaan th/123;124 berhenti di 2024. Kalau lo memaksa th/125 untuk var 284, respons yang balik tidak berisi sel data yang lo harapkan. Selalu cek daftar tahun di respons sebelum menyimpulkan bahwa datanya kosong.
Kesalahan apa yang paling sering muncul?
Empat kegagalan di bawah ini menutup hampir semua kasus yang bikin request gagal, dan semuanya sudah direproduksi langsung terhadap server BPS pada 8 November 2026. Tidak ada yang misterius: semuanya soal parameter yang hilang atau format key yang berubah saat disalin.
| Respons |
Penyebab |
Perbaikan |
400 Missing required parameter: key. |
Segmen /key// kosong |
Isi API key, jangan andalkan env var yang belum diekspor |
400 Invalid parameter: key must be alphanumeric only. |
Key tersalin dalam bentuk URL-encoded, mengandung %2B atau %3D |
Salin key mentah, jangan dari address bar browser |
302 saat membuka webapi.bps.go.id |
Root domain bukan endpoint API, hanya redirect |
Panggil path lengkap /v1/api/list/model/data/... |
InterpolationSyntaxError di Python |
Key berisi % dibaca configparser standar |
Pakai configparser.RawConfigParser |
Baris terakhir itu jebakan yang paling mahal waktunya karena error-nya muncul di sisi klien, bukan di sisi server. Kalau key lo mengandung karakter persen, configparser biasa akan mencoba melakukan interpolasi dan melempar exception sebelum request pertama dikirim. Ganti ke RawConfigParser, atau simpan key sebagai environment variable dan baca dengan os.environ.
Keterbatasan Data
Beberapa hal tidak bisa disimpulkan dari API ini, dan sebaiknya disebut apa adanya di laporan lo. Pertama, API mengirim angka beserta kode periode, bukan tanggal rilis resmi per sel. Stempel last_update berlaku di level respons, jadi klaim "dirilis tanggal sekian" tetap harus merujuk ke siaran pers BPS, bukan ke JSON. Kedua, cakupan default domain/0000 adalah nasional. Angka provinsi, kabupaten, atau kota butuh kode domain lain, dan tidak semua indikator tersedia di semua level. Ketiga, ketersediaan tahun berbeda per variabel: var 184 punya 2024 dan 2025, var 284 pada pengujian ini hanya 2023 dan 2024. Keempat, latensi dan ketersediaan layanan tidak diukur di sini, jadi artikel ini tidak mengklaim SLA apa pun. Terakhir, angka kemiskinan yang dipakai adalah agregat kota plus desa (vervar 3). Kalau lo butuh angka perkotaan atau perdesaan saja, ambil vervar 1 atau 2 dan jangan mencampurnya dalam satu deret.
Bagaimana kalau fetcher-nya mau jalan tiap hari?
Pipeline data yang jalan sendiri butuh tiga hal: mesin yang hidup terus, penyimpanan untuk snapshot, dan kuota model untuk merangkum angka jadi narasi. Untuk mesin, free tier Alibaba Cloud cukup buat menjalankan cron fetcher dan penyimpanan snapshot JSON harian, karena beban satu request API per hari itu kecil. Untuk bagian perangkuman otomatis, AI scene coding Alibaba Cloud menyediakan jalur cepat kalau lo mau menambah lapisan narasi tanpa membangun semuanya dari nol. Yang penting bukan merek mesinnya, tapi disiplin menyimpan snapshot bertanggal supaya angka yang sudah tayang bisa diaudit ulang.
Sumber
FAQ
Apakah API BPS gratis?
Gratis, tapi tetap butuh API key yang didaftarkan lewat akun pengguna di situs BPS. Key dipakai sebagai bagian dari path, bukan header, jadi siapa pun yang membaca URL lo bisa melihatnya. Simpan di file terpisah dan jangan pernah menempelkannya di kode yang di-commit ke repositori publik.
Berapa lama data baru muncul di API?
Tidak ada jaminan waktu yang tertulis di dokumentasi publik. Pada pengujian 8 November 2026, data kemiskinan semester 2 2025 sudah tersedia untuk var 184, sementara var 284 baru sampai 2024. Cek daftar tahun di respons setiap kali menarik data, jangan mengasumsikan tahun berjalan sudah ada.
Bisakah mengambil data sampai level kabupaten dan kota?
Bisa untuk beberapa indikator, dengan mengganti domain/0000 menjadi kode domain wilayah yang bersangkutan. Tidak semua variabel tersedia di semua level, jadi selalu cek vervar dan data-availability di respons. Kalau kuncinya kosong, artinya kombinasi wilayah dan indikator itu memang tidak diterbitkan.
Apakah perlu library tambahan selain urllib?
Tidak. urllib.request dan json dari pustaka standar sudah cukup untuk satu request dan parsing dasar. Library seperti requests atau httpx lebih nyaman kalau lo butuh retry, connection pooling, atau banyak request paralel, tapi bukan syarat untuk mulai.
Apa arti kode domain 0000?
0000 adalah kode untuk level nasional, dan itu yang dipakai contoh di artikel ini. Kode lain merujuk provinsi atau wilayah administratif lain sesuai katalog BPS. Kalau lo tidak yakin kode yang benar, ambil dulu daftar domain dari endpoint katalog, jangan menebak angka.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬