KasirPro API v1
Base URL: https://api.kasirpro.com ·
Dokumen mesin: GET /v1 (JSON) & /llms.txt (markdown). Halaman ini memuat kedua bahasa di HTML-nya.
Machine docs: GET /v1 (JSON) & /llms.txt (markdown). This page contains both languages in its HTML.
Ikhtisar
API resmi KasirPro untuk aplikasi apa pun yang bisa memanggil HTTP — backend web/mobile, sistem pemesanan, dashboard, middleware, skrip otomasi, hingga AI agent. Prinsip terpenting:
- Khusus lisensi MAX & Unlimited. Akun PRO ditolak dengan 403
license_tier. - Satu kunci = satu toko. Token
kp_live_…mengidentifikasi toko sekaligus akun — tidak ada parameter toko di endpoint mana pun. Akun multi toko memakai kunci berbeda per toko (maks 3 kunci/toko). - Izin (scope) per kunci:
produk,stok,pelanggan,laporan,transaksi,order. - Mode kunci: Hanya Baca (semua GET) atau Baca+Tulis (juga POST).
- Tidak disediakan: HPP/biaya modal tidak pernah dikembalikan; stok, transaksi, kas, dan uang tidak bisa ditulis; tidak ada akses lintas toko.
Overview
The official KasirPro API for any application that can make HTTP calls — web/mobile backends, ordering systems, dashboards, middleware, automation scripts, and AI agents alike. Core principles:
- MAX & Unlimited licenses only. PRO accounts are rejected with 403
license_tier. - One key = one store. The
kp_live_…token identifies both the store and the account — no store parameter exists on any endpoint. Multi-store accounts use a separate key per store (max 3 keys/store). - Scopes per key:
produk,stok,pelanggan,laporan,transaksi,order. - Key mode: Read-only (all GET) or Read+Write (POST too).
- Deliberately not provided: cost price (HPP) is never returned; stock, transactions, cash and money cannot be written; no cross-store access.
Autentikasi
Buat kunci di backoffice.kasirpro.com → menu API Akses (pilih toko, izin, dan mode). Kunci tampil sekali — simpan sebagai environment variable.
Authentication
Create a key at backoffice.kasirpro.com → API Akses (choose store, scopes and mode). The key is shown once — store it as an environment variable.
curl -H "Authorization: Bearer kp_live_..." https://api.kasirpro.com/v1/me
Wajib HTTPS. Batas 120 request/menit per kunci — saat 429, hormati header Retry-After.
HTTPS required. Limit 120 requests/minute per key — on 429, honor the Retry-After header.
Format & Error
Semua jawaban JSON UTF-8. Tanggal YYYY-MM-DD; nominal uang = integer Rupiah. Bentuk error selalu sama:
Format & Errors
All responses are UTF-8 JSON. Dates are YYYY-MM-DD; money values are integer Rupiah. Errors always share one shape:
{
"error": true,
"code": "scope_required",
"message": "API key ini tidak punya izin 'laporan'. Buat/ubah key di backoffice."
}
| HTTP | code | ArtiMeaning | |
|---|---|---|---|
| 401 | unauthorized | Kunci tidak dikenal / dinonaktifkan. | Unknown or disabled key. |
| 403 | scope_required | Kunci tidak punya izin endpoint ini. | Key lacks the endpoint's scope. |
| 403 | write_not_allowed | Kunci hanya-baca dipakai di endpoint POST. | Read-only key used on a POST endpoint. |
| 403 | license_tier | Lisensi bukan MAX/Unlimited. | License is not MAX/Unlimited. |
| 403 | license_expired | Lisensi backoffice kedaluwarsa. | Backoffice license expired. |
| 403 | account_disabled / toko_deleted | Akun dinonaktifkan / toko kunci dihapus. | Account disabled / the key's store was deleted. |
| 404 | not_found | Data/endpoint tidak ditemukan. | Data or endpoint not found. |
| 405 | method_not_allowed | Method salah (GET/POST sesuai endpoint). | Wrong method (GET/POST per endpoint). |
| 422 | invalid_param | Parameter/body tidak valid — message menjelaskan. | Invalid parameter/body — message explains. |
| 429 | rate_limited | >120 request/menit. Ada header Retry-After. | >120 requests/minute. Includes Retry-After. |
| 5xx | server_error / store_error / xendit_failed | Gangguan server / Toko Online / pembuatan QRIS. | Server / online-store / QRIS creation failure. |
Pagination endpoint daftar: page (mulai 1, maks 400) & per (default 50, maks 100).
Pagination on list endpoints: page (from 1, max 400) & per (default 50, max 100).
GET /v1/ping
Cek koneksi & validitas kunci.Check connectivity & key validity.
{ "ok": true, "waktu_server": "2026-08-26T14:05:11+07:00" }
GET /v1/me
Identitas kunci: akun, lisensi, toko, mode, dan izin. Mulailah dari sini.The key's identity: account, license, store, mode and scopes. Start here.
{
"nama": "Budi Santoso",
"lisensi": "MAX",
"aktif_sampai": "2027-01-15",
"toko": { "id": 12, "nama": "Kedai Kopi Melati" },
"mode": "baca+tulis",
"scopes": ["produk", "laporan", "order"]
}
GET /v1/toko
Profil toko milik kunci ini.The key's store profile.
{
"data": {
"id": 12, "nama": "Kedai Kopi Melati",
"alamat": "Jl. Melati No. 5", "kota": "Bandung",
"telp": "0227654321", "timezone": "Asia/Jakarta"
}
}
GET /v1/produk produk
Daftar produk toko — tanpa HPP/biaya modal.The store's products — cost price never included.
| Param | KeteranganDescription | |
|---|---|---|
q | Cari pada nama / SKU (opsional). | Search name / SKU (optional). |
page, per | Pagination (lihat Format). | Pagination (see Format). |
curl -H "Authorization: Bearer kp_live_..." \
"https://api.kasirpro.com/v1/produk?q=kopi&per=2"
{
"page": 1, "per": 2,
"data": [
{ "id": 345, "toko": 12, "nama": "Kopi Susu Gula Aren", "sku": "KSG-01",
"satuan": "cup", "kategori": "Minuman", "harga": 22000, "aktif": true },
{ "id": 351, "toko": 12, "nama": "Kopi Tubruk", "sku": "",
"satuan": "cup", "kategori": "Minuman", "harga": 15000, "aktif": true }
]
}
GET /v1/stok stok
Stok per produk (dijumlah lintas varian, mengikuti mode desimal toko). resep:true = produk berbahan: stok fisik lazim 0 — ketersediaan sebenarnya dari bahan, tidak dihitung endpoint ini.
Stock per product (summed across variants, following the store's decimal mode). resep:true = recipe product: physical stock is usually 0 — real availability derives from ingredients, not computed here.
| Param | KeteranganDescription | |
|---|---|---|
q | Cari nama produk (opsional). | Search product name (optional). |
page, per | Pagination. | Pagination. |
{
"page": 1, "per": 50, "toko": 12,
"data": [
{ "produk_id": 345, "nama": "Kopi Susu Gula Aren", "satuan": "cup", "stok": 0, "resep": true },
{ "produk_id": 402, "nama": "Air Mineral 600ml", "satuan": "btl", "stok": 47, "resep": false }
]
}
POST /v1/produk produk Baca+Tulis
Tambah produk baru. Tersinkron ke perangkat kasir ≤ 1 menit.Create a product. Syncs to cashier devices within ~1 minute.
| Field | KeteranganDescription | |
|---|---|---|
nama* | Nama produk (maks 50 karakter). | Product name (max 50 chars). |
harga* | Harga jual, integer Rupiah ≥ 0. | Sell price, integer Rupiah ≥ 0. |
sku, satuan, deskripsi | Opsional. | Optional. |
kategori_id | Opsional — harus kategori milik toko ini. | Optional — must belong to this store. |
stok | Stok awal (opsional, default 0). | Initial stock (optional, default 0). |
curl -X POST https://api.kasirpro.com/v1/produk \
-H "Authorization: Bearer kp_live_..." -H "Content-Type: application/json" \
-d '{"nama":"Es Teh Manis","harga":8000,"satuan":"cup","stok":0}'
{
"ok": true, "produk_id": 512,
"catatan": "Perangkat kasir menerima produk ini lewat sinkronisasi (<=1 menit)."
}
POST /v1/produk/ubah produk Baca+Tulis
Ubah sebagian field produk — hanya field yang dikirim yang berubah. Bisa diubah: nama, harga, sku, satuan, deskripsi, kategori_id. HPP dan stok tidak bisa diubah lewat API.Partial update — only sent fields change. Editable: nama, harga, sku, satuan, deskripsi, kategori_id. Cost price and stock cannot be changed via the API.
curl -X POST https://api.kasirpro.com/v1/produk/ubah \
-H "Authorization: Bearer kp_live_..." -H "Content-Type: application/json" \
-d '{"id":512,"harga":9000}'
{ "ok": true, "produk_id": 512 }
GET /v1/pelanggan pelanggan
Daftar pelanggan toko. piutang = tagihan berjalan pelanggan (Rupiah).The store's customers. piutang = the customer's outstanding receivable (Rupiah).
| Param | KeteranganDescription | |
|---|---|---|
q | Cari nama / no. HP (opsional). | Search name / phone (optional). |
page, per | Pagination. | Pagination. |
{
"page": 1, "per": 50,
"data": [
{ "id": 88, "toko": 12, "nama": "Siti Rahma", "nohp": "081234567890",
"alamat": "Jl. Anggrek 3", "piutang": 150000 }
]
}
POST /v1/pelanggan pelanggan Baca+Tulis
Tambah pelanggan baru ke toko ini.Create a customer in this store.
| Field | KeteranganDescription | |
|---|---|---|
nama* | Nama pelanggan (maks 50 karakter). | Customer name (max 50 chars). |
nohp, alamat | Opsional. | Optional. |
curl -X POST https://api.kasirpro.com/v1/pelanggan \
-H "Authorization: Bearer kp_live_..." -H "Content-Type: application/json" \
-d '{"nama":"Siti Rahma","nohp":"081234567890"}'
{ "ok": true, "pelanggan_id": 913 }
POST /v1/pelanggan/ubah pelanggan Baca+Tulis
Ubah sebagian data pelanggan: nama, nohp, alamat.Partial customer update: nama, nohp, alamat.
curl -X POST https://api.kasirpro.com/v1/pelanggan/ubah \
-H "Authorization: Bearer kp_live_..." -H "Content-Type: application/json" \
-d '{"id":913,"nohp":"081298765432"}'
{ "ok": true, "pelanggan_id": 913 }
GET /v1/laporan/ringkasan laporan
Omzet & jumlah transaksi per hari. Omzet = total − refund (NET), rumus yang sama dengan laporan backoffice.Daily revenue & transaction count. Revenue = total − refund (net), matching the backoffice reports.
| Param | KeteranganDescription | |
|---|---|---|
from, to | YYYY-MM-DD; default bulan berjalan; rentang maks 366 hari. | YYYY-MM-DD; defaults to current month; range ≤366 days. |
curl -H "Authorization: Bearer kp_live_..." \
"https://api.kasirpro.com/v1/laporan/ringkasan?from=2026-08-01&to=2026-08-07"
{
"from": "2026-08-01", "to": "2026-08-07",
"total": { "trx": 214, "omzet": 8425000 },
"per_hari": [
{ "tanggal": "2026-08-01", "trx": 31, "omzet": 1180000 },
{ "tanggal": "2026-08-02", "trx": 28, "omzet": 1035000 }
]
}
GET /v1/laporan/produk laporan
Penjualan per produk, urut nilai terbesar — rumus identik Laporan Penjualan backoffice (qty ikut desimal & dikurangi retur; nota dibatalkan tidak dihitung).Per-product sales, ordered by value — the exact backoffice Sales Report formula (decimal qty, returns deducted; voided receipts excluded).
| Param | KeteranganDescription | |
|---|---|---|
from, to | Rentang tanggal (maks 366 hari). | Date range (≤366 days). |
page, per | Pagination. | Pagination. |
{
"from": "2026-08-01", "to": "2026-08-07", "page": 1, "per": 50,
"data": [
{ "produk_id": 345, "nama": "Kopi Susu Gula Aren", "qty": 182, "nilai": 4004000 },
{ "produk_id": 402, "nama": "Air Mineral 600ml", "qty": 95.5, "nilai": 477500 }
]
}
GET /v1/transaksi transaksi
Daftar nota, terbaru dulu. metode kosong ditampilkan sebagai "Tunai".Receipt list, newest first. Empty metode is shown as "Tunai" (cash).
| Param | KeteranganDescription | |
|---|---|---|
from, to | Rentang tanggal (maks 366 hari). | Date range (≤366 days). |
page, per | Pagination. | Pagination. |
{
"from": "2026-08-01", "to": "2026-08-07", "page": 1, "per": 50,
"data": [
{ "id": 26612345, "toko": 12, "tanggal": "2026-08-07", "waktu": "14:22:31",
"nota": "KM26877102", "total": 57000, "refund": 0, "metode": "QrisToko", "piutang": 0 }
]
}
GET /v1/transaksi/detail transaksi
Satu nota lengkap dengan rincian biaya dan item. total_baris = harga total baris (sudah × qty, setelah diskon item).One receipt with charge breakdown and items. total_baris = the line total (already × qty, after item discount).
| Param | KeteranganDescription | |
|---|---|---|
id* | id nota dari /v1/transaksi. | Receipt id from /v1/transaksi. |
{
"nota": {
"id": 26612345, "toko": 12, "tanggal": "2026-08-07", "waktu": "14:22:31",
"no": "KM26877102", "subtotal": 52000, "diskon": 0, "pajak": 5000,
"layanan": 0, "ongkir": 0, "total": 57000, "refund": 0, "metode": "QrisToko"
},
"items": [
{ "nama": "Kopi Susu Gula Aren", "qty": 2, "qty_retur": 0, "total_baris": 44000, "nilai_retur": 0 },
{ "nama": "Es Teh Manis", "qty": 1, "qty_retur": 0, "total_baris": 8000, "nilai_retur": 0 }
]
}
POST /v1/order order Baca+Tulis
Buat pesanan Toko Online + kode QRIS dalam satu panggilan. Harga dihitung server mengikuti aturan toko (promo / harga grosir / harga pelanggan). Pesanan langsung tampil di aplikasi kasir sebagai pesanan online; setelah QRIS dibayar, nota dibuat otomatis.
Create an online-store order plus a QRIS payment code in one call. Prices are computed server-side following the store's rules (promos / wholesale / customer pricing). The order appears in the cashier app immediately; once the QRIS is paid, the receipt is created automatically.
| Field | KeteranganDescription | |
|---|---|---|
nama* | Nama pemesan. | Customer name. |
nohp | No. HP pemesan (9–15 digit; opsional). Bila diisi, pelanggan otomatis terdaftar/tertaut. | Customer phone (9–15 digits; optional). If present, the customer is auto-created/linked. |
meja_id | Opsional — id meja untuk pesanan dine-in. | Optional — table id for dine-in orders. |
items* | Maks 100 baris: {produk_id*, varian_id, qty* (1–999), catatan}. | Max 100 lines: {produk_id*, varian_id, qty* (1–999), catatan}. |
curl -X POST https://api.kasirpro.com/v1/order \
-H "Authorization: Bearer kp_live_..." -H "Content-Type: application/json" \
-d '{
"nama": "Budi", "nohp": "081234567890",
"items": [
{ "produk_id": 345, "qty": 2 },
{ "produk_id": 351, "qty": 1, "catatan": "tanpa gula" }
]
}'
{
"ok": true,
"order_id": 9812,
"savednota_id": 5541,
"qris": {
"qris_id": "qr_8f2f6c1e-2c3a-4f6d-9d21-7f1b2a9c0e55",
"qr_string": "00020101021226670016ID.CO.XENDIT.WWW01189360091100...6304A1B2",
"amount": 59000,
"orderid": 77120,
"expires_at": "2026-08-26T09:35:00.000Z"
},
"catatan": "Render qris.qr_string sebagai QR code utk dibayar. Cek pembayaran lewat GET /v1/order/status?id=9812. Pesanan tampil di aplikasi kasir sebagai pesanan online."
}
qr_string dirender menjadi gambar QR (QRIS dinamis, kedaluwarsa ±30 menit). amount sudah termasuk pajak/biaya sesuai pengaturan toko.
Render qr_string as a QR image (dynamic QRIS, expires in ~30 minutes). amount already includes tax/charges per the store's settings.
GET /v1/order/status order
Status pembayaran pesanan. Poll tiap 5–10 detik sampai paid:true atau ±30 menit (QRIS kedaluwarsa).Order payment status. Poll every 5–10 seconds until paid:true or ~30 minutes (QRIS expiry).
| Param | KeteranganDescription | |
|---|---|---|
id* | order_id dari POST /v1/order. | order_id from POST /v1/order. |
// belum dibayar / unpaid:
{ "order_id": 9812, "paid": false, "status": "pending", "total": 59000 }
// sudah dibayar / paid:
{ "order_id": 9812, "paid": true, "status": "settlement", "total": 59000 }
Praktik Terbaik
- Mulai dengan
GET /v1/meuntuk mengetahui toko, mode, dan scope kunci. - Cache data master (
/v1/toko,/v1/produk) — jarang berubah. - Saat
429, tunggu sesuaiRetry-After; jangan retry agresif. - Simpan kunci sebagai environment variable; jangan pernah tanam di kode yang dibagikan.
- Versi markdown dokumen ini: /llms.txt (mis. untuk dimasukkan ke konteks AI agent).
Best Practices
- Start with
GET /v1/meto learn the key's store, mode and scopes. - Cache master data (
/v1/toko,/v1/produk) — it changes rarely. - On
429, wait perRetry-After; never retry aggressively. - Keep keys in environment variables; never embed them in shared code.
- Markdown version of this document: /llms.txt (e.g. to feed into an AI agent's context).
KasirPro · backoffice.kasirpro.com