API dan MCP Borneo Sawit: harga TBS harian, tanpa API key
Semua harga yang kami tampilkan di situs ini juga tersedia sebagai JSON, terbuka untuk siapa saja, tanpa kunci dan tanpa pendaftaran. Halaman ini menjelaskan bentuk datanya lebih dulu, baru cara mengambilnya, karena kesalahan yang paling sering terjadi bukan soal HTTP melainkan soal arti angkanya.
Apa yang sebenarnya Anda ambil
Satu baris data adalah satu harga, untuk satu tanggal, satu PKS atau satu RAM, dan satu pelapor. Bukan rata-rata dan bukan indeks.
Dua pelapor bisa menyebut harga berbeda untuk PKS yang sama di hari yang sama. Keduanya kami tampilkan berdampingan, tidak dirata-ratakan, karena selisihnya itu sendiri adalah informasi.
Tanggal adalah tanggal kalender WITA (UTC+8), bukan instan. Harga yang dilaporkan jam tujuh pagi tetap milik hari itu, bukan hari sebelumnya menurut UTC.
Koreksi ditambahkan sebagai baris baru, tidak menimpa yang lama. Yang Anda baca selalu revisi yang sedang tayang.
Harga pintu PKS dan harga RAM ke petani adalah dua klaim berbeda dan tidak boleh dijumlahkan atau dirata-ratakan bersama. Yang satu dibayar pabrik di pintunya, yang satu dibayar peron kepada petani di lokasinya, dan selisihnya adalah margin peron.
Field `change` bernilai null kalau pasangan itu baru pertama kali melaporkan, dan 0 kalau harganya tidak bergerak. Keduanya berbeda; jangan memperlakukan null sebagai nol.
Cakupan kami adalah Kalimantan Selatan. Ini bukan harga CPO, bukan indeks nasional, dan bukan lembar resmi Disbun, walaupun angka acuan kemitraan Disbun terbaru ikut kami sertakan di setiap papan sebagai pembanding.
Mulai dari sini
Tidak ada API key untuk membaca. Tidak ada pendaftaran, tidak ada token, tidak ada header apa pun yang wajib. Salin baris ini dan Anda sudah punya papan harga hari ini.
curl -s https://borneosawit.com/api/v1/prices/latest
Jawabannya membawa tanggal yang benar-benar dijelaskannya. Kalau hari ini belum ada laporan, yang keluar adalah hari terakhir yang ada isinya, dengan tanggalnya sendiri, bukan array kosong. CORS terbuka untuk semua origin, jadi `fetch` dari browser juga jalan. Basis URL-nya `https://borneosawit.com/api/v1`.
Endpoint
Sembilan, semuanya GET, semuanya JSON, semuanya anonim. Setiap kesalahan memakai amplop yang sama: `{ "error": { "code", "message", "hint", "docs" } }`, dan yang perlu Anda cabang adalah `code`, bukan `message`.
- /api/v1/prices/latest
- Papan harga paling baru: hari ini WITA, atau hari terakhir yang ada isinya.
- /api/v1/prices/{date}
- Papan untuk satu tanggal persis. Hari kosong tetap 200 dengan array kosong.
- /api/v1/prices/history
- Satu pasangan PKS dan pelapor selama beberapa hari berturut-turut. Wajib `millId` dan `reporterId`.
- /api/v1/mills
- Semua PKS, beserta setiap bentuk penulisan namanya.
- /api/v1/rams
- Semua loading ram, beserta wilayah dan aliasnya.
- /api/v1/reporters
- Semua pelapor harga: PKS yang menerbitkan harganya sendiri, dan peron yang melaporkan.
- /api/v1/articles
- Daftar artikel tanpa isi badannya. `?locale=` untuk satu bahasa saja.
- /api/v1/articles/{slug}
- Satu artikel lengkap, badannya sebagai daftar blok.
- /api/v1/status
- Database menjawab atau tidak, dan tanggal harga terbaru. Tidak pernah di-cache.
MCP: hubungkan langsung ke Claude
Data yang sama juga tersedia sebagai MCP server anonim, dengan tujuh alat. Tidak ada login, tidak ada OAuth, tidak ada token yang perlu dipasang.
claude mcp add --transport http borneo-sawit https://borneosawit.com/mcp
Di Claude Code, jalankan perintah di atas. Di aplikasi Claude, tambahkan sebagai custom connector dengan URL `https://borneosawit.com/mcp` dan biarkan bagian autentikasinya kosong.
Transport-nya Streamable HTTP di atas POST, stateless, tanpa session id dan tanpa SSE. GET dijawab 405, dan itu memang jawaban yang benar untuk server yang tidak pernah mengirim pesan sendiri.
Alatnya: `get_price_board`, `get_price_history`, `list_mills`, `list_rams`, `list_reporters`, `list_articles`, `get_article`. Tidak ada satupun yang menulis.
Dokumen yang bisa dibaca mesin
Selain endpoint di atas, setiap halaman situs ini juga menjawab `Accept: text/markdown` dengan versi markdown-nya sendiri.
- /openapi.json
Spesifikasi OpenAPI 3.1 untuk seluruh API di atas
- /.well-known/mcp.json
Manifest MCP, dalam bentuk server.json milik registry
- /llms.txt
Ringkasan situs untuk model bahasa
- /sitemap.xml
Setiap URL yang kami minta diindeks, dalam tiga bahasa
Kalau Anda yang melaporkan harga
Menulis harga adalah permukaan yang berbeda dan tertutup. Endpoint-nya `https://borneosawit.com/api/mcp`, memakai OAuth 2.1 dengan PKCE, dan pendaftaran klien dinamis terbuka di `https://borneosawit.com/api/oauth/register` sehingga Claude bisa mendaftarkan dirinya sendiri. Yang tidak terbuka adalah akunnya: hanya pelapor terdaftar yang bisa menyetujui koneksi, dan tidak ada endpoint di halaman ini yang bisa mengubah satu angka pun. Kalau Anda PKS atau peron yang ingin harganya tayang di sini, hubungi kami lewat WhatsApp.
CLI
Ada CLI Node tanpa dependensi di folder `cli/` dalam repositori ini. Belum kami terbitkan ke npm, dan halaman ini akan mengatakannya begitu sudah. Sementara ini jalankan langsung dari checkout, atau pakai `curl` seperti contoh di atas.
node cli/bin/borneo-sawit.mjs prices
Istilah yang muncul di dalam data
Nama field ditulis dalam bahasa Inggris, tetapi nilainya tidak diterjemahkan. Enam istilah ini muncul apa adanya di dalam respons, dan sengaja tidak dicarikan padanan.
- TBS
- Tandan Buah Segar, tandan yang dijual petani per kilogram. Satu-satunya yang dihargai di sini.
- PKS
- Pabrik Kelapa Sawit. Membeli TBS di pintu pabriknya sendiri.
- RAM
- Loading ram: halaman pengepul yang membeli TBS langsung dari petani lalu mengangkutnya ke PKS. Harganya harga ke petani, bukan harga pintu pabrik.
- peron
- Pengepul. Kata yang sama dipakai untuk dua peran yang kami pisahkan: peron sebagai pelapor harga PKS, dan RAM sebagai penetap harga ke petani. Halaman yang sama sering keduanya.
- Disbun
- Dinas Perkebunan. Menetapkan harga acuan kemitraan secara berkala; angka terbarunya ikut di setiap papan sebagai pembanding.
- kabupaten
- Wilayah administratif setingkat kabupaten. Namanya tidak pernah diterjemahkan, karena nama itu juga kunci pencocokannya.