API Access & Webhooks
Diperbarui: 2026-07-24~13 menit baca
API Access & Webhooks
Terakhir diperbarui / Last updated: 2026-07-24 Halaman / Page:
/pengaturan/developerVersi / Version: 1.0
Catatan Audiens / Audience Note
[ID] Artikel ini ditulis untuk tim teknis Anda (developer internal atau vendor yang membangun integrasi) — bukan untuk pengguna sehari-hari FirstJournal. Kalau Anda tidak berencana menyambungkan FirstJournal ke sistem lain lewat kode, Anda mungkin tidak memerlukan halaman ini.
[EN] This article is written for your technical team (in-house developers or a vendor building an integration) — not for everyday FirstJournal users. If you don't plan to connect FirstJournal to another system via code, you likely don't need this page.
Ringkasan / Overview
[ID] API Access & Webhooks memungkinkan sistem eksternal (ERP, BI tool, aplikasi mobile custom, atau agent AI Anda sendiri) membaca dan menulis data FirstJournal lewat REST API, serta menerima notifikasi otomatis (webhook) saat kejadian tertentu terjadi — misalnya invoice baru dibuat atau pembayaran diterima.
[EN] API Access & Webhooks lets an external system (ERP, BI tool, a custom mobile app, or your own AI agent) read and write FirstJournal data via a REST API, and receive automatic notifications (webhooks) when certain events happen — such as a new invoice being created or a payment being received.
Siapa yang Bisa Mengakses / Who Can Access This
[ID]
- Plan: hanya tersedia di plan Enterprise dan Enterprise Pro. Plan Free/Starter/Pro tidak memiliki akses ini dan akan melihat layar ajakan upgrade di halaman
/pengaturan/developer. - Pengecualian: organisasi bertipe Personal (mode "Keuangan Pribadi") mendapat akses API tanpa syarat plan Enterprise, karena datanya milik satu pengguna sendiri.
- Role: hanya Owner dan Admin yang bisa membuat/mengelola API key dan webhook. Role lain akan melihat pesan "Hanya Owner/Admin yang dapat mengelola API Keys dan Webhook."
[EN]
- Plan: available only on the Enterprise and Enterprise Pro plans. Free/Starter/Pro plans do not have this access and will see an upgrade prompt on the
/pengaturan/developerpage. - Exception: organizations in Personal mode ("Keuangan Pribadi") get API access without the Enterprise plan requirement, since the data belongs to a single user.
- Role: only Owner and Admin can create/manage API keys and webhooks. Other roles see the message "Hanya Owner/Admin yang dapat mengelola API Keys dan Webhook."
Di Mana Menemukannya / Where to Find It
[ID] Buka Pengaturan → Developer API (URL: /pengaturan/developer). Halaman ini punya 3 tab: API Keys, Webhook, dan Dokumentasi.
[EN] Go to Pengaturan → Developer API (URL: /pengaturan/developer). The page has 3 tabs: API Keys, Webhook, and Dokumentasi.
Tab API Keys — Membuat & Mengelola Key
[ID]
- Di tab API Keys, klik tombol "Buat API Key".
- Isi Nama Key (maks. 50 karakter, contoh: "Shopee Auto-Sync").
- Centang minimal satu Scope — scope dikelompokkan per modul: Invoice (
invoices:read,invoices:write), Kontak (contacts:read,contacts:write), Produk (products:read), Laporan (reports:read), Kas & Bank (cash:read,cash:write), Jurnal (journals:read), plus scope Partner API untuk integrasi aplikasi konsumen/mobile: Outlet (outlets:read), Menu (menu:read), Loyalty (loyalty:read,loyalty:history:read,loyalty:write), Order (orders:read), Brand/Storefront (storefront:read). - Pilih Kedaluwarsa: Tidak pernah, 30 hari, 90 hari, 1 tahun, atau tanggal kustom.
- Klik "Buat API Key". Sistem akan menampilkan raw key HANYA SEKALI di layar "Simpan API Key Ini Sekarang" — salin dan simpan sekarang, karena tidak bisa ditampilkan ulang. Anda wajib mencentang kotak pengakuan sebelum bisa menutup layar ini.
- Maksimal 10 API key aktif per organisasi (tombol "Buat API Key" nonaktif otomatis kalau sudah mencapai batas).
- Di tabel API Keys, Anda bisa ganti nama (ikon pensil) atau cabut akses (ikon tempat sampah, dengan konfirmasi — tindakan ini tidak dapat dibatalkan). Kolom yang ditampilkan: Nama, Scopes, Last Digunakan, Kedaluwarsa, Status (Aktif/Kedaluwarsa/Nonaktif), Total Request.
[EN]
- In the API Keys tab, click "Buat API Key" ("Create API Key").
- Fill in Nama Key (Key Name, max 50 chars, e.g. "Shopee Auto-Sync").
- Check at least one Scope — grouped by module: Invoice (
invoices:read,invoices:write), Kontak/Contact (contacts:read,contacts:write), Produk/Product (products:read), Laporan/Reports (reports:read), Kas & Bank/Cash (cash:read,cash:write), Jurnal/Journals (journals:read), plus Partner API scopes for consumer/mobile app integrations: Outlet (outlets:read), Menu (menu:read), Loyalty (loyalty:read,loyalty:history:read,loyalty:write), Order (orders:read), Brand/Storefront (storefront:read). - Choose Kedaluwarsa (Expiry): Never, 30 days, 90 days, 1 year, or a custom date.
- Click "Buat API Key". The system shows the raw key ONLY ONCE on the "Simpan API Key Ini Sekarang" ("Save This API Key Now") screen — copy and store it now, it cannot be shown again. You must check the acknowledgement box before you can close this screen.
- Maximum 10 active API keys per organization (the "Buat API Key" button auto-disables once the limit is hit).
- In the API Keys table you can rename (pencil icon) or revoke (trash icon, with a confirmation — this action cannot be undone). Columns shown: Nama (Name), Scopes, Last Digunakan (Last Used), Kedaluwarsa (Expiry), Status (Aktif/Kedaluwarsa/Nonaktif — Active/Expired/Inactive), Total Request.
Cara Memanggil API / How to Call the API
[ID] Semua endpoint v1 menggunakan header:
Authorization: Bearer fj_live_<key Anda>
Format key: fj_live_ diikuti 64 karakter hex. Key disimpan sistem sebagai hash SHA-256 saja — FirstJournal sendiri tidak menyimpan raw key setelah ditampilkan sekali di awal.
[EN] All v1 endpoints use the header:
Authorization: Bearer fj_live_<your key>
Key format: fj_live_ followed by 64 hex characters. The system stores only a SHA-256 hash of the key — FirstJournal itself does not retain the raw key after the one-time reveal.
Batas Kecepatan / Rate Limits
[ID]
| Plan | Per Menit | Per Jam |
|---|---|---|
| Enterprise | 150 | 3.000 |
| Enterprise Pro | 500 | 10.000 |
Setiap response API v1 menyertakan header X-RateLimit-Limit-Minute, X-RateLimit-Remaining-Minute, X-RateLimit-Limit-Hour, X-RateLimit-Remaining-Hour, dan X-RateLimit-Reset. Kalau melebihi batas, Anda akan menerima status 429 dengan header Retry-After.
[EN]
| Plan | Per Minute | Per Hour |
|---|---|---|
| Enterprise | 150 | 3,000 |
| Enterprise Pro | 500 | 10,000 |
Every v1 API response includes the headers X-RateLimit-Limit-Minute, X-RateLimit-Remaining-Minute, X-RateLimit-Limit-Hour, X-RateLimit-Remaining-Hour, and X-RateLimit-Reset. If you exceed the limit, you'll get a 429 status with a Retry-After header.
Endpoint yang Tersedia / Available Endpoints
[ID] Daftar lengkap dan contoh request/response ada di tab Dokumentasi pada halaman /pengaturan/developer (dibuat khusus per organisasi, langsung menampilkan base URL firstjournal.id). Ringkasannya:
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/invoices | invoices:read |
| POST | /api/v1/invoices | invoices:write |
| GET | /api/v1/invoices/:id | invoices:read |
| GET | /api/v1/contacts | contacts:read |
| POST | /api/v1/contacts | contacts:write |
| GET | /api/v1/contacts/:id | contacts:read |
| GET | /api/v1/products | products:read |
| GET | /api/v1/products/:id | products:read |
| GET | /api/v1/reports/profit-loss?dateFrom=&dateTo= | reports:read |
| GET | /api/v1/outlets | outlets:read |
| GET | /api/v1/outlets/:id | outlets:read |
| GET | /api/v1/menu | menu:read |
| GET | /api/v1/loyalty/config | loyalty:read |
| GET | /api/v1/loyalty/members/:phoneOrCode | loyalty:read |
| GET | /api/v1/loyalty/members/:phoneOrCode/history | loyalty:history:read |
| POST | /api/v1/loyalty/members | loyalty:write |
| PATCH | /api/v1/loyalty/members/:phoneOrCode | loyalty:write |
| GET | /api/v1/orders | orders:read |
| GET | /api/v1/orders/:id | orders:read |
| GET | /api/v1/brand | storefront:read |
Endpoint Menu, Loyalty, Order, Brand/Outlet disebut Partner API — ditujukan untuk aplikasi konsumen/mobile pihak ketiga (bukan untuk sinkronisasi akuntansi ERP). Data menu sengaja tidak menyertakan harga pokok/costBasis karena ini data yang bisa dilihat konsumen.
[EN] The full list and request/response examples live in the Dokumentasi ("Docs") tab on the /pengaturan/developer page (rendered per-organization, showing the base URL firstjournal.id directly). Summary above.
The Menu, Loyalty, Order, Brand/Outlet endpoints are the Partner API — meant for third-party consumer/mobile apps (not for ERP accounting sync). The menu data intentionally excludes cost basis since this is consumer-viewable data.
MCP Server — Untuk AI Agent / For AI Agents
[ID] Selain REST, FirstJournal juga menyediakan endpoint MCP (Model Context Protocol) di POST https://firstjournal.id/api/mcp — dipakai kalau tim Anda punya AI agent sendiri (misalnya untuk analisis data bisnis) dan ingin agent itu mengakses data FirstJournal lewat tool yang sudah dipahami AI, bukan raw REST call. Key dan scope yang dipakai sama persis dengan API key REST Anda (header Authorization: Bearer fj_live_...) — tidak ada key terpisah untuk MCP.
[EN] Besides REST, FirstJournal also exposes an MCP (Model Context Protocol) endpoint at POST https://firstjournal.id/api/mcp — used when your team has its own AI agent (e.g. for business data analysis) and wants that agent to access FirstJournal data through AI-native tools instead of raw REST calls. The key and scopes used are exactly the same as your REST API key (header Authorization: Bearer fj_live_...) — there is no separate key for MCP.
Tab Webhook — Notifikasi Real-Time
[ID]
- Di tab Webhook, klik "Tambah Webhook".
- Isi Nama (maks. 100 karakter) dan URL — URL wajib HTTPS, kalau tidak sistem menolak dengan pesan "URL harus menggunakan HTTPS."
- Centang minimal satu Event, dikelompokkan: Invoice (
invoice.created,invoice.paid,invoice.voided), Kontak (contact.created), Pembayaran (payment.received). - Klik "Tambah Webhook". Sama seperti API key, secret webhook ditampilkan hanya sekali di layar "Simpan Webhook Secret Ini" — salin sekarang untuk verifikasi signature.
- Maksimal 20 webhook per organisasi.
- Webhook table mendukung hapus dan edit.
[EN]
- In the Webhook tab, click "Tambah Webhook" ("Add Webhook").
- Fill in Nama (Name, max 100 chars) and URL — the URL must be HTTPS, otherwise the system rejects it with "URL harus menggunakan HTTPS" ("URL must use HTTPS").
- Check at least one Event, grouped as: Invoice (
invoice.created,invoice.paid,invoice.voided), Kontak/Contact (contact.created), Pembayaran/Payment (payment.received). - Click "Tambah Webhook". Like the API key, the webhook secret is shown only once on the "Simpan Webhook Secret Ini" ("Save This Webhook Secret") screen — copy it now to verify signatures.
- Maximum 20 webhooks per organization.
- The webhook table supports delete and edit.
Memverifikasi Signature Webhook / Verifying the Webhook Signature
[ID] Setiap payload webhook dikirim dengan header X-FirstJournal-Signature: sha256=<hmac>. HMAC dihitung sebagai HMAC-SHA256(secret_mentah, isi_payload). Contoh verifikasi di sisi Anda:
const sig = crypto.createHmac("sha256", rawSecret).update(body).digest("hex");
const expected = req.headers["x-firstjournal-signature"].replace("sha256=", "");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
// tolak request — signature tidak valid
}
[EN] Every webhook payload is sent with the header X-FirstJournal-Signature: sha256=<hmac>. The HMAC is computed as HMAC-SHA256(raw_secret, payload_body). Verification example on your side:
const sig = crypto.createHmac("sha256", rawSecret).update(body).digest("hex");
const expected = req.headers["x-firstjournal-signature"].replace("sha256=", "");
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
// reject the request — invalid signature
}
Kebijakan Retry Webhook / Webhook Retry Policy
[ID] Kalau endpoint Anda gagal merespons (bukan HTTP 2xx, atau timeout), FirstJournal mencoba ulang otomatis:
| Percobaan | Jeda |
|---|---|
| 1 | Langsung |
| 2 | 1 menit |
| 3 | 5 menit |
| 4+ | 30 menit → ditandai gagal permanen (abandoned) |
Setelah 3 kali gagal, status pengiriman menjadi abandoned dan tidak dicoba lagi. Status pengiriman lain: pending (belum dicoba), delivered (sukses, HTTP 2xx).
[EN] If your endpoint fails to respond (non-2xx, or times out), FirstJournal retries automatically:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4+ | 30 minutes → marked permanently abandoned |
After 3 failures, delivery status becomes abandoned and is no longer retried. Other delivery statuses: pending (not yet attempted), delivered (succeeded, HTTP 2xx).
Panduan Keamanan / Security Guidance
[ID]
- Jangan pernah bagikan API key atau webhook secret Anda — siapa pun yang memegangnya bisa membaca (dan, tergantung scope, menulis) data akuntansi Anda.
- Kalau key/secret pernah terlihat orang lain (misalnya ter-commit ke repository publik), segera cabut lewat ikon tempat sampah di tabel API Keys dan buat key baru.
- Beri scope seminim mungkin sesuai kebutuhan integrasi — jangan pilih semua scope kalau integrasi Anda hanya butuh baca data laporan.
- Gunakan kedaluwarsa (30/90 hari) untuk key yang dipakai sementara (migrasi data, testing), bukan "Tidak pernah".
- Selalu verifikasi signature webhook (lihat bagian di atas) sebelum memproses payload — mencegah orang lain mengirim payload palsu ke endpoint Anda.
- URL webhook wajib HTTPS — sistem menolak URL HTTP biasa.
[EN]
- Never share your API key or webhook secret — whoever holds it can read (and, depending on scope, write) your accounting data.
- If a key/secret was ever exposed (e.g. committed to a public repository), immediately revoke it via the trash icon in the API Keys table and create a new one.
- Grant the minimum scope your integration actually needs — don't select every scope if your integration only needs to read report data.
- Use an expiry (30/90 days) for temporary-use keys (data migration, testing), not "Never".
- Always verify the webhook signature (see above) before processing a payload — this prevents someone else from sending a fake payload to your endpoint.
- Webhook URLs must be HTTPS — the system rejects plain HTTP URLs.
Pertanyaan Umum / FAQ
Q: Siapa yang bisa membuat API key? A: Hanya user dengan role Owner atau Admin. Role lain tidak bisa melihat/mengelola API Keys atau Webhook di halaman ini.
Q: Who can create an API key? A: Only users with the Owner or Admin role. Other roles cannot view/manage API Keys or Webhook on this page.
Q: Saya lupa menyalin API key saat pertama kali dibuat, bagaimana? A: Key tidak bisa ditampilkan ulang. Cabut key lama (ikon tempat sampah) dan buat key baru.
Q: I forgot to copy my API key when it was first created — what now? A: The key can't be shown again. Revoke the old key (trash icon) and create a new one.
Q: Apakah plan Pro bisa pakai API? A: Tidak. API Access hanya untuk plan Enterprise dan Enterprise Pro (kecuali organisasi mode Personal, yang mendapat akses tanpa syarat plan).
Q: Can the Pro plan use the API? A: No. API Access is Enterprise and Enterprise Pro only (except Personal-mode organizations, which get access regardless of plan).
Q: Berapa banyak API key/webhook yang bisa saya buat? A: Maksimal 10 API key aktif dan 20 webhook per organisasi.
Q: How many API keys/webhooks can I create? A: Maximum 10 active API keys and 20 webhooks per organization.
Q: Apakah ada dokumentasi endpoint yang lebih lengkap dengan contoh request/response?
A: Ya, buka tab Dokumentasi di halaman /pengaturan/developer — sudah berisi base URL dan contoh untuk semua endpoint, termasuk Partner API.
Q: Is there more complete endpoint documentation with request/response examples?
A: Yes, open the Dokumentasi ("Docs") tab on the /pengaturan/developer page — it includes the base URL and examples for every endpoint, including the Partner API.
Fitur Terkait / Related Features
- Pengaturan — Pengaturan perusahaan tempat halaman Developer API berada
- Keamanan Data — Praktik keamanan umum FirstJournal
Changelog
| Tanggal | Perubahan |
|---|---|
| 2026-07-24 | Initial documentation created — ditulis berdasarkan verifikasi source code (src/app/(dashboard)/pengaturan/developer/page.tsx, DeveloperPageClient.tsx, src/components/developer/CreateApiKeyModal.tsx, CreateWebhookModal.tsx, RawKeyRevealModal.tsx, ApiKeyTable.tsx, src/lib/constants/plan-limits.ts) dan docs/features/23-api-access.md. |
Apakah artikel ini membantu?