Bab 13 · Developer API
Kode Error & Pemecahan Masalah
Daftar lengkap kode error beserta penyebabnya, kebijakan percobaan ulang, dan jawaban untuk masalah yang paling sering muncul.
Bentuk error
Semua error memakai bentuk yang sama:
{ "error": { "code": "invalid_limit", "message": "limit must be an integer between 1 and 500." } }
Gunakan error.code untuk logika program. error.message ditujukan untuk manusia dan kata-katanya bisa berubah.
Daftar lengkap kode error
| HTTP | code | Penyebab | Cara memperbaiki |
|---|---|---|---|
| 400 | invalid_limit | limit bukan bilangan bulat 1–500 | Pakai nilai 1–500 |
| 400 | invalid_date | Parameter tanggal tidak bisa dibaca | Pakai ISO 8601, contoh 2026-08-13T00:00:00Z |
| 400 | invalid_parameter | Angka negatif atau pecahan, atau nilai enum di luar daftar | Cek tipe dan daftar nilai di Referensi Endpoint |
| 400 | invalid_cursor | cursor rusak atau bukan berasal dari respons API | Jangan ubah cursor; kalau ragu, mulai lagi tanpa cursor |
| 400 | invalid_id | {id} di path bukan bilangan bulat minimal 1 | Periksa URL yang dibentuk program Anda |
| 401 | missing_api_key | Header Authorization tidak ada atau salah bentuk | Kirim Authorization: Bearer lsk_live_... |
| 401 | invalid_api_key | Key tidak dikenal atau tidak diawali lsk_ | Pastikan key tersalin utuh |
| 401 | revoked_api_key | Key sudah dicabut | Buat key baru di Pengaturan → API Key |
| 401 | expired_api_key | Key sudah kedaluwarsa | Buat key baru |
| 404 | not_found | Objek tidak ada, atau sudah dihapus | Endpoint per-id tidak melayani data terhapus |
| 429 | rate_limited | Melebihi 60 request per menit per key, atau 120 per menit per IP | Tunggu sesuai Retry-After |
| 500 | internal_error | Kesalahan di sisi server | Coba ulang dengan jeda bertingkat; kalau terus terjadi, hubungi tim Lensiro dengan URL dan waktunya |
Metode selain GET dijawab 405 tanpa body error.
Kebijakan percobaan ulang
| Status | Boleh diulang? | Cara |
|---|---|---|
| 400, 401, 404 | Tidak | Perbaiki request atau key dulu — mengulang akan gagal lagi |
| 429 | Ya | Tunggu sebanyak detik di Retry-After, lalu ulangi request yang sama |
| 500 | Ya | Jeda bertingkat: 1 detik, 2, 4, 8, maksimal lima kali |
| Timeout jaringan | Ya | Aman — semua endpoint hanya membaca, jadi mengulang tidak mengubah apa pun |
Pemecahan masalah
Semua request dijawab 401 padahal key baru dibuat
Urut dari yang paling sering: ada spasi atau baris baru ikut tersalin; kata Bearer hilang atau tanpa spasi; key ditaruh di query string, yang tidak didukung; atau key sudah dicabut. Cek dengan /ping lebih dulu — kalau /ping berhasil tapi endpoint lain gagal, masalahnya bukan di key.
data kosong padahal datanya jelas ada
- Zona waktu. Filter tanggal memakai UTC. "Hari ini" di WIB dimulai pukul
17:00Zhari sebelumnya. Ini penyebab nomor satu. - Salah ketik nama parameter. Parameter yang tidak dikenal diabaikan diam-diam, jadi
branch=2(bukanbranch_id=2) tidak menimbulkan error tapi juga tidak menyaring apa pun. - Filter saling meniadakan, misalnya
transaction_date_fromlebih besar daripadatransaction_date_to. updated_sinceterlalu baru karena checkpoint Anda sudah maju lebih dulu.
Angka rekap saya beda dengan laporan di aplikasi
Periksa berurutan:
- Zona waktu — laporan aplikasi memakai waktu lokal, API memakai UTC.
- Transaksi batal ikut terkirim secara default. Buang
status = "CANCELED"kalau laporan pembanding tidak menghitungnya. - Kolom yang dibandingkan —
total(sebelum klaim asuransi) tidak sama dengannet_total(setelah klaim asuransi). - Uang masuk vs omzet —
/sales/paymentsdikelompokkan per tanggal bayar,/salesper tanggal order. Untuk transaksi yang dicicil, keduanya memang berbeda. - Paginasi berhenti terlalu cepat — pastikan loop berjalan sampai
has_morebernilaifalse.
Ada transaksi yang masuk dua kali ke sistem saya
Sistem Anda melakukan insert, bukan upsert. Ini memang harus ditangani: updated_since bersifat inklusif dan sengaja mengirim ulang baris di batas waktu, ditambah baris yang berubah saat paginasi berjalan. Kuncinya id — untuk pergerakan stok, id yang berbentuk string.
Transaksi yang dihapus tidak pernah hilang dari sistem saya
Anda belum memakai include_deleted=true. Tanpa itu, data terhapus berhenti terkirim tanpa penanda apa pun, dan salinan Anda tidak pernah tahu.
Stok di API tidak cocok dengan aplikasi
Cek as_of di respons — kalau snapshot Anda sudah lama, tarik ulang. Kalau masih beda, lihat bagian Rekonsiliasi di halaman API Gudang; penyebab yang paling sering adalah rentang tanggal pergerakan yang memotong sebagian riwayat.
Barang sudah dikirim antar cabang tapi TRANSFER_IN belum muncul
Memang begitu perilakunya: TRANSFER_IN baru tercatat setelah cabang tujuan mengonfirmasi penerimaan di aplikasi. Selama barang di perjalanan, stok berkurang di cabang asal dan belum bertambah di cabang tujuan.
Saldo poin pelanggan tidak pernah diperbarui
Perubahan poin tidak mengubah updated_at pelanggan, jadi polling updated_since tidak akan mengirimnya ulang. Poll /members/{id}/point-logs, atau lakukan full refresh /members secara berkala.
Backfill kena 429 terus
Tarik per rentang bulanan, satu halaman pada satu waktu, dan beri jeda sekitar satu detik antar request. Menaikkan limit ke 500 mengurangi jumlah request, tapi untuk /sales payload-nya jadi besar karena item dan pembayaran ikut menyatu — 100 sampai 200 biasanya paling seimbang.
Responsnya lambat
Perkecil limit, dan persempit filter dengan branch_id atau rentang tanggal. /warehouse/stocks dan /warehouse/stock-movements paling berat karena dihitung ulang dari seluruh riwayat — jadwalkan di luar jam sibuk toko.
Melaporkan masalah
Kalau masalahnya tampak berasal dari sisi Lensiro, kirimkan ke tim Lensiro: URL lengkap yang dipanggil (tanpa API key), waktu kejadian beserta zona waktunya, kode status dan body error yang diterima, serta nama key yang dipakai. Dengan itu kejadiannya bisa ditelusuri di log server.

