# Paginasi, error, dan idempotensi

> Cara daftar dipecah per halaman, bentuk error, cara mengulang penulisan dengan aman, serta format uang dan tanggal.

Source: https://docs.bakasir.com/id/docs/developers/conventions

## Respons

Satu objek dikembalikan sebagai `data`:

```json
{ "data": { "id": "01K9ZT6Q2X3M8N4V7B5C1D0EFG", "name": "Es Kopi Susu" } }
```

Daftar dikembalikan sebagai `data` dengan kolom paginasi:

```json
{ "data": [], "has_more": false, "next_cursor": null }
```

## Paginasi

Daftar memakai kursor. Kirim `limit` (1 sampai 200, bawaan 50) dan, untuk halaman berikutnya, `next_cursor` dari halaman sebelumnya:

```bash
curl "https://api.bakasir.com/v1/sales?limit=100&cursor=MDFLOVpUNlEyWDNNOE40VjdCNUMxRDBFRkc" \
  -H "Authorization: Bearer bak_kunci_anda"
```

- Hasil diurutkan dari terlama ke terbaru. Tambahkan `order=desc` untuk terbaru dahulu.
- Teruskan selama `has_more` bernilai `true`. Saat `false`, `next_cursor` bernilai `null`.
- Kursor bersifat buram. Jangan membuat atau mengubahnya. Kursor yang salah mengembalikan `400` dengan kode `invalid_cursor`.
- Data baru yang dibuat saat Anda berpindah halaman muncul di akhir, jadi sinkronisasi penuh cukup dilanjutkan sampai `has_more` bernilai `false`.

## Error

Setiap error berbentuk sama. `code` stabil dan ditujukan untuk program Anda, `error` adalah kalimat yang mudah dibaca.

```json
{ "error": "not found", "code": "not_found" }
```

| Status | Kode | Arti |
| --- | --- | --- |
| 400 | `invalid_request` | Isi permintaan atau nilai query tidak valid |
| 400 | `invalid_cursor` | Kursor tidak valid |
| 401 | `invalid_api_key`, `revoked_api_key` | Lihat [Autentikasi](https://docs.bakasir.com/id/docs/developers/authentication.md) |
| 403 | `insufficient_scope`, `plugin_inactive`, `tenant_inactive` | Lihat [Autentikasi](https://docs.bakasir.com/id/docs/developers/authentication.md) |
| 403 | `subscription_read_only`, `subscription_suspended` | Langganan jatuh tempo, sehingga menulis atau membaca diblokir |
| 403 | `email_verification_required` | Pemilik belum memverifikasi alamat email |
| 404 | `not_found` | Data tidak ada atau milik bisnis lain |
| 409 | `conflict` | Perubahan bentrok dengan data yang ada, misalnya kode produk ganda |
| 413 | `payload_too_large` | Isi permintaan lebih dari 1 MB |
| 422 | `unknown_store`, `unknown_product` | Outlet atau produk yang dirujuk tidak ada |
| 422 | `idempotency_key_reused` | `Idempotency-Key` dipakai untuk permintaan yang berbeda |
| 429 | `rate_limited` | Terlalu banyak permintaan |
| 5xx | `server_error`, `unavailable` | Ada kegagalan di sisi kami. Ulangi dengan jeda bertahap |

## Idempotensi

Jaringan bisa gagal. Untuk mengulang penulisan tanpa membuatnya dua kali, kirim header `Idempotency-Key` berisi nilai unik hingga 200 karakter pada permintaan `POST`, `PATCH`, dan `DELETE`:

```bash
curl https://api.bakasir.com/v1/customers \
  -H "Authorization: Bearer bak_kunci_anda" \
  -H "Idempotency-Key: impor-2026-11-04-baris-18" \
  -H "Content-Type: application/json" \
  -d '{"name": "Sari Dewi", "phone": "081200000000"}'
```

- Respons pertama disimpan selama 24 jam. Pengulangan dengan kunci dan isi yang sama mengembalikannya lagi, dengan header `Idempotent-Replayed: true`, dan tidak ada yang dibuat dua kali.
- Kunci yang sama dengan permintaan berbeda mengembalikan `422` `idempotency_key_reused`.
- Permintaan yang masih berjalan mengembalikan `409` `idempotency_in_progress`. Tunggu sebentar lalu ulangi.
- Error server (5xx) tidak disimpan, jadi Anda bisa mengulanginya dengan kunci yang sama.

## Uang, jumlah, dan tanggal

- Nominal seperti `price`, `cost`, dan `total` berupa bilangan bulat dalam satuan terkecil mata uang bisnis. Untuk rupiah, `22000` berarti Rp22.000. Untuk mata uang bersen, `1250` berarti 12,50.
- Jumlah (qty) berupa angka dan boleh desimal, misalnya `0.5` kilogram.
- Stempel waktu memakai RFC 3339 dalam UTC, misalnya `2026-11-04T08:30:00Z`. Pada filter seperti `from` dan `to` Anda juga bisa mengirim tanggal seperti `2026-11-04`, yang dibaca dalam zona waktu bisnis.
- ID berupa teks. Perlakukan sebagai nilai buram.
