1. Panduan Pengguna (UI)
1.1 Dashboard
Halaman utama setelah login (/dashboard).
Fitur:
- Statistik utama: total kontak, broadcast WA, device terhubung, funnel aktif
- Kartu paket: menampilkan paket aktif & limit pemakaian
- Grafik kontak baru (6 bulan terakhir)
- Performa broadcast (delivery rate, sukses/gagal)
- Broadcast terbaru (5 terakhir dengan status)
- Akses cepat ke semua fitur
1.2 Manajemen Kontak
URL: /contacts
Fitur
- Daftar Kontak — Tabel kontak (nama, telepon, email, perusahaan, tags)
- Contact Lists — Grup/segmentasi kontak
- Tambah Kontak — Form dengan field: nama, telepon (format 62xx), email, perusahaan, tags, notes
- Import CSV — Upload file CSV ke dalam list (header: name, phone, email, company, tags, notes)
- Webhook — Endpoint unik per list untuk integrasi eksternal (dengan JWT token)
Import CSV
Header: name, phone, email, company, tags, notes
Baris: John Doe,6281234567890,john@mail.com,ACME Corp,premium,Customer baru
Webhook
POST /api/webhooks/lists/{listId}?token={jwt}
{ "name": "...", "phone": "62812...", "email": "...", "company": "...", "tags": "...", "notes": "..." }
1.3 WhatsApp
URL: /whatsapp
1.3.1 Device Management
- Daftar Device — Nama, status, nomor telepon
- Tambah Device — Buat instance baru
- Aktivasi — Scan QR Code untuk menghubungkan WhatsApp
- Tes Kirim — Kirim pesan test ke nomor sendiri
- Logout / Hapus — Putuskan koneksi
1.3.2 Broadcast WA
URL: /whatsapp/broadcasts
- Kirim pesan massal ke kontak/list
- Dukungan media (gambar)
- Penjadwalan (tentukan waktu kirim)
- Riwayat broadcast (status, total, sukses, gagal)
1.3.3 Jadwal WA
URL: /whatsapp/schedules
- Jadwal pesan berulang (repeatable)
- Dukungan cron expression
- Pilih kontak/list + device
1.4 Email
URL: /email
1.4.1 Akun & Domain
- Akun email otomatis dengan domain default: nama@ngirimpesan.my.id
- Tambah domain kustom (SPF, DKIM, DMARC)
- Buat akun email (local part + password)
- Kirim test email untuk verifikasi
1.4.2 Broadcast Email
URL: /email/broadcasts
- Pilih akun email pengirim
- Pilih kontak/list
- Tulis subject + body (text & HTML)
- Jadwalkan pengiriman
1.4.3 Konfigurasi Email Client
URL: /email/config
Informasi SMTP/IMAP untuk menggunakan email client eksternal (Outlook, Thunderbird, dll):
- IMAP: mail.ngirimpesan.id port 993 (SSL)
- SMTP: mail.ngirimpesan.id port 465 (SSL)
1.5 Auto Copy Funnel
URL: /funnels
Fitur unggulan — rangkaian pesan otomatis multi-channel dengan bantuan AI.
1.5.1 Membuat Funnel
- Buka Funnels → Buat Funnel
- Isi: nama, goal, deskripsi produk, target audience, channel (WA/Email/Campuran), jumlah pesan, nada bicara
- Klik Generate dengan AI
- Review hasil generate, edit jika perlu, lalu simpan
Contoh hasil AI:
Step 1 (WA) — Langsung dikirim
"Halo {nama}! Masih ingat dengan {produk}? Ada penawaran spesial!"
Delay: 0 detik | Kondisi: sent
Step 2 (Email) — +1 hari
Subject: Tips maksimalin {produk}
"Halo {nama}, kami punya tips..."
Delay: 86400 detik | Kondisi: timeout
1.5.2 Aktivasi Funnel
- Pilih target: Contact list atau Form Opt-in
- Klik Aktivasi
- Sistem enroll contacts & jalankan step otomatis via queue
1.5.3 Analytics
URL: /funnels/{id}/analytics
Statistik: total sent, opened, clicked, converted per step + activity log.
1.6 Landing Pages
URL: /landing-pages
- Generate HTML landing page dengan AI (Tailwind CSS + Lucide Icons)
- Input: judul, deskripsi, target, warna, gaya
- Bisa embed form opt-in
- Publikasikan → akses via /lp/{slug}
1.7 Form Opt-in
URL: /form-optins
- Buat form dengan field kustom
- Embed di website eksternal
<div id="ngirimpesan-form-{formId}"></div>
<script src="{app_url}/public/form-embed.js" data-form-id="{formId}"></script>
- Setiap submit: lead tersimpan + contact auto-created + funnel enrollment otomatis
1.8 Pricing & Subscription
URL: /pricing
- Pilih paket → Checkout via Tripay → Bayar
- Plan otomatis aktif setelah pembayaran
- Plan expiry dicek setiap jam oleh worker
1.9 Admin Panel
URL: http://admin.ngirimpesan.id:6060
- Dashboard statistik global
- Manajemen user (plan, limits, status, admin role)
- Manajemen paket harga (CRUD)
- Mail server management (domain, account, DNS)
1.10 Webmail
URL: /mailbox/{accountId}
Webmail client: inbox, sent, compose, vacation auto-reply, filters.
2. Dokumentasi API
2.1 API Server
Ngirimpesan memiliki API server terpisah untuk integrasi eksternal:
| Server | Port | Auth | Digunakan Untuk |
|---|---|---|---|
| Main App | 5555 | Cookie auth_id | Inertia SPA pages (Dashboard, dll) |
| API Server | 5566 | Authorization: Bearer <token> | Integrasi eksternal (semua endpoint /api/*) |
Base URL API Server: https://api.ngirimpesan.id
Semua endpoint /api/* di bawah menggunakan API server dengan Bearer token.
Endpoint tanpa prefix/api/(misal/contacts/store,/whatsapp/broadcast) hanya tersedia di Main App (port 5555) dengan cookie auth — digunakan oleh Inertia UI, bukan untuk integrasi eksternal.
2.2 Autentikasi
Login (Web UI)
POST /login
Content-Type: application/json
{ "email": "user@example.com", "password": "password123" }
Response: 302 Found dengan cookie auth_id={jwt}
Register
POST /register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"password_confirmation": "password123"
}
Google OAuth
GET /google/redirect → Redirect ke Google login
GET /google/callback?code=xxx → Proses callback
Verify Email
GET /verify-email/{token}
POST /verify-email/resend
Password Reset
POST /forgot-password
{ "email": "user@example.com" }
POST /reset-password
{ "token": "...", "password": "newpassword", "password_confirmation": "newpassword" }
API Token Authentication
Untuk mengakses API server (port 5566), gunakan Authorization: Bearer header:
GET /api/funnels
Authorization: Bearer np_a1b2c3d4e5f6...
Token didapatkan dari halaman Profile → API Tokens di aplikasi utama.
2.3 API Token Management
Kelola token API dari halaman Profile atau via endpoint berikut (cookie auth di port 5555):
List Tokens
GET /api/tokens
Response:
{
"success": true,
"tokens": [
{ "id": "uuid", "name": "Production API", "token_prefix": "np_a1b2c3d4...", "last_used_at": 1690000000, "created_at": 1690000000 }
]
}
Create Token
POST /api/tokens
{ "name": "Production API" }
Response: {"success": true, "token": {"id": "uuid", "name": "Production API", "token_prefix": "np_a1b2c3d4...", "plain_token": "np_a1b2c3d4e5f6..."}}
Penting: plain_token hanya ditampilkan sekali. Simpan di tempat aman.
Revoke Token
DELETE /api/tokens/{id}
Response: {"success": true}
2.4 Contacts API
Endpoint kontak tanpa prefix /api/ (seperti /contacts/store) menggunakan cookie auth di Main App (port 5555) — digunakan oleh Inertia UI.
Untuk integrasi eksternal, gunakan endpoint Webhook (/api/webhooks/...) di API server (port 5566) dengan Authorization: Bearer.
Create Contact
POST /contacts/store
Cookie: auth_id={token}
{
"name": "John Doe",
"phone": "6281234567890",
"email": "john@example.com",
"company": "ACME Corp",
"tags": "premium",
"notes": "Customer baru",
"list_id": "uuid-list-id"
}
Response: {"success": true, "contact": {"id": "uuid", "name": "John Doe"}}
Note: Jika nomor sudah ada, data akan di-update (merge).
Update Contact
POST /contacts/{id}/update
Delete Contact
POST /contacts/{id}/destroy
Contact List
POST /contacts/lists/store → { "name": "...", "description": "..." }
POST /contacts/lists/{id}/destroy
POST /contacts/lists/{id}/members → { "contact_ids": ["uuid1", "uuid2"] }
POST /contacts/lists/{id}/members/{contactId}/remove
GET /contacts/lists/{id}/members → { "members": [...] }
Import CSV
POST /contacts/lists/{id}/import
Content-Type: multipart/form-data
File: data.csv (header: name,phone,email,company,tags,notes)
Response: {"success": true, "imported": 45, "failed": 2, "errors": [...]}
Webhook Add Member (API Server)
POST /api/webhooks/lists/{listId}?token={jwt}
Authorization: Bearer {your_api_token}
{ "name": "...", "phone": "62812...", "email": "...", "company": "...", "tags": "...", "notes": "..." }
Response: {"success": true, "contact_id": "uuid"}
2.5 WhatsApp API
Endpoint device & broadcast (tanpa prefix /api/) menggunakan cookie auth di Main App — digunakan oleh Inertia UI. Hanya callback WA server yang melalui API server.
Device (Main App — Cookie Auth)
GET /whatsapp → Inertia page
POST /whatsapp → { "name": "Marketing Device" }
POST /whatsapp/{id}/activate → { "status": "connecting", ... }
GET /whatsapp/{id}/qr → { "qr": "base64..." }
POST /whatsapp/{id}/logout
POST /whatsapp/{id}/destroy
POST /whatsapp/{id}/test
Broadcast (Main App — Cookie Auth)
POST /whatsapp/broadcast
{
"name": "Promo July",
"wa_device_id": "device-uuid",
"message": "Halo {nama}! Promo spesial...",
"media_url": "https://...",
"contact_list_id": "list-uuid",
"contact_ids": ["uuid1"],
"scheduled_at": "2026-07-22T10:00:00Z"
}
Response: {"success": true, "broadcast": {"id": "uuid", "status": "queued"}}
Schedule (Main App — Cookie Auth)
POST /whatsapp/schedule
{
"name": "Weekly Newsletter",
"whatsapp_id": "device-uuid",
"message": "Halo {nama}!...",
"contact_list_id": "list-uuid",
"schedule_type": "repeating",
"scheduled_at": "2026-07-22T08:00:00Z",
"repeat_cron": "0 8 * * 1"
}
Callback dari WA Server (Public)
POST /api/whatsapp/notify
{ "id": "device-uuid", "status": "qr", "qr": "base64..." }
Status: qr, connected, sleep, restricted
SSE Real-time QR (Main App)
GET /whatsapp/sse
Server-Sent Events untuk streaming QR code.
Single Send (API Server — Bearer Token)
Kirim satu pesan WhatsApp ke satu nomor secara langsung:
POST /api/whatsapp/send
Authorization: Bearer {your_api_token}
{
"wa_device_id": "device-uuid",
"phone": "6281234567890",
"message": "Halo {nama}! Promo spesial cuma hari ini!",
"media_url": "https://example.com/image.jpg" // optional
}
Response: {"success": true, "data": {...}}
Error: {"error": "WhatsApp device is not connected"} atau {"error": "Failed to send message", "detail": "..."}
2.6 Email API
Endpoint akun & domain (tanpa prefix /api/) menggunakan cookie auth di Main App. Berikut endpoint di API server:
Akun & Domain (Main App — Cookie Auth)
POST /email/accounts → { "name": "...", "localPart": "info", "password": "...", "domain": "..." }
POST /email/accounts/{id}/destroy
POST /email/accounts/{id}/update
POST /email/accounts/{id}/test
POST /email/domains → { "name": "mycompany.com" }
POST /email/domains/{id}/destroy
GET /email/domains/{id}/dns
POST /email/domains/{id}/verify-dns
Broadcast (API Server — Bearer Token)
POST /api/email/broadcasts
Authorization: Bearer {your_api_token}
{
"email_account_id": "uuid",
"name": "Newsletter July",
"subject": "Newsletter Bulan Ini",
"text_body": "Halo {nama}!...",
"html_body": "<h1>Halo {nama}</h1><p>...</p>",
"from_name": "Info Perusahaan",
"contact_list_id": "list-uuid",
"contact_ids": ["uuid1"],
"scheduled_at": "2026-07-25T09:00:00Z"
}
GET /api/email/broadcasts
GET /api/email/broadcasts/{id}
POST /api/email/broadcasts/{id}/cancel
Schedule (API Server — Bearer Token)
POST /api/email/schedules
Authorization: Bearer {your_api_token}
{
"email_account_id": "uuid",
"name": "Monthly Newsletter",
"subject": "...",
"text_body": "...",
"html_body": "...",
"contact_list_id": "list-uuid",
"schedule_type": "repeating",
"scheduled_at": "2026-08-01T08:00:00Z",
"repeat_cron": "0 8 1 * *"
}
GET /api/email/schedules
GET /api/email/schedules/{id}
PUT /api/email/schedules/{id}
DELETE /api/email/schedules/{id}
Single Send (API Server — Bearer Token)
Kirim satu email ke satu alamat secara langsung (tidak melalui broadcast queue):
POST /api/email/send
Authorization: Bearer {your_api_token}
{
"email_account_id": "account-uuid",
"to": "user@example.com",
"to_name": "John Doe", // optional
"subject": "Halo {nama}!",
"text_body": "Halo John, ini pesan dari kami.", // optional
"html_body": "<h1>Halo John</h1><p>Ini pesan dari kami.</p>" // optional
}
Response: {"success": true, "message": "Email sent successfully"}
Error: {"error": "Email quota exceeded", "quota": {...}} atau {"error": "Failed to send email", "detail": "..."}
Minimal salah satu daritext_bodyatauhtml_bodyharus diisi. Email dikirim langsung via SMTP ke server Stalwart tanpa melalui antrian.
2.7 Funnel API
Semua endpoint funnel menggunakan API server (port 5566) dengan Bearer token:
Generate dengan AI
POST /api/funnels/generate
Authorization: Bearer {your_api_token}
{
"goal": "Konversi trial ke paid",
"product_description": "Aplikasi kirim pesan otomatis",
"audience": "Pemilik UKM",
"messageCount": 4,
"channel": "campuran",
"tone": "santai"
}
Response:
{
"success": true,
"steps": [
{ "stepOrder": 1, "channel": "wa", "body": "Halo {nama}!...", "condition": "sent", "delaySeconds": 0 },
{ "stepOrder": 2, "channel": "email", "subject": "Tips...", "body": "...", "condition": "timeout", "delaySeconds": 86400 }
]
}
CRUD Funnel
Authorization: Bearer {your_api_token}
POST /api/funnels → Buat funnel (dengan steps)
GET /api/funnels → Daftar funnel
GET /api/funnels/{id} → Detail + steps
PUT /api/funnels/{id} → Update
DELETE /api/funnels/{id} → Hapus
POST /api/funnels/{id}/activate → Aktifkan
POST /api/funnels/{id}/pause → Jeda
PUT /api/funnels/{id}/steps/{stepId} → Update step
Create Funnel
POST /api/funnels
Authorization: Bearer {your_api_token}
{
"name": "Konversi Trial",
"goal": "Konversi trial ke paid",
"product_description": "Aplikasi kirim pesan",
"audience": "Pemilik UKM",
"channel": "campuran",
"tone": "santai",
"contact_list_id": "list-uuid",
"source_type": "contact_list",
"steps": [
{ "stepOrder": 1, "channel": "wa", "condition": "sent", "delaySeconds": 0, "body": "Halo {nama}!...", "fallbackAction": null }
]
}
Analytics
GET /api/funnels/{id}/analytics
Authorization: Bearer {your_api_token}
Response:
{
"summary": {
"totalSent": 150,
"totalOpened": 89,
"totalClicked": 45,
"totalConverted": 12,
"steps": [
{ "stepOrder": 1, "channel": "wa", "sent": 150, "opened": 89, "clicked": 45, "converted": 12 }
],
"recentActivity": [...]
}
}
Templates
Authorization: Bearer {your_api_token}
POST /api/funnels/templates → Simpan template
GET /api/funnels/templates → Daftar template
GET /api/funnels/templates/{id}
DELETE /api/funnels/templates/{id}
2.8 Landing Page API
Semua endpoint landing page menggunakan API server (port 5566) dengan Bearer token:
Generate dengan AI
POST /api/landing-pages/generate
{
"title": "Aplikasi Kirim Pesan Otomatis",
"description": "Kirim pesan WA & Email otomatis dengan AI",
"audience": "Pemilik bisnis UKM",
"colors": "biru",
"style": "modern",
"form_optin_id": "form-uuid"
}
Response: {"success": true, "html": "<script src=...><div...", "form_optin_id": "form-uuid"}
CRUD
Authorization: Bearer {your_api_token}
POST /api/landing-pages → { "title": "...", "slug": "...", "html_content": "...", "form_optin_id": "..." }
PUT /api/landing-pages/{id}
DELETE /api/landing-pages/{id}
POST /api/landing-pages/{id}/publish
Public Preview
GET /lp/{slug} → HTML (public, no auth)
2.9 Form Opt-in API
Endpoint CRUD menggunakan API server (port 5566) dengan Bearer token. Endpoint embed & submit bersifat publik (CORS).
CRUD
Authorization: Bearer {your_api_token}
POST /api/form-optins
{
"name": "Form Download Ebook",
"description": "...",
"fields": "[{\"key\":\"name\",\"label\":\"Nama\",\"type\":\"text\",\"required\":true},{\"key\":\"email\",\"label\":\"Email\",\"type\":\"email\",\"required\":true}]",
"redirect_url": "https://example.com/thanks",
"submit_button_text": "Download",
"success_message": "Terima kasih!",
"list_id": "list-uuid",
"is_active": 1
}
PUT /api/form-optins/{id}
DELETE /api/form-optins/{id}
Leads
GET /api/form-optins/{id}/leads?page=1&limit=50
Response:
{
"leads": [{ "id": "uuid", "data": "{...}", "parsed_data": {...}, "ip_address": "...", "created_at": "..." }],
"pagination": { "page": 1, "limit": 50, "total": 120, "totalPages": 3 }
}
Embed (Public, CORS)
GET /api/form-optins/{id}/embed?access_key=xxx
Response: {"id": "...", "name": "...", "fields": [...], "submit_button_text": "...", "success_message": "..."}
Submit (Public, CORS)
POST /api/form-optins/{id}/submit
{ "name": "John", "email": "john@mail.com", "phone": "6281234567890" }
Response: {"success": true, "message": "Terima kasih!", "redirect_url": "https://..."}
2.10 Admin API
Admin panel berjalan di Main App (port 6060). Semua endpoint admin membutuhkan cookie auth_id dengan is_admin: true.
Dashboard
GET /admin/api/dashboard/stats
Users
GET /admin/users
GET /admin/users/{id}
POST /admin/api/users/{id}/plan → { "plan_id": "uuid" }
POST /admin/api/users/{id}/limits → { "whatsapp_limit": 10, "email_accounts_limit": 50, ... }
POST /admin/api/users/{id}/toggle
POST /admin/api/users/{id}/toggle-admin
DELETE /admin/api/users/{id}
Plans
GET /admin/plans
POST /admin/api/plans
{
"name": "Pro",
"price": 150000,
"whatsapp_limit": 5,
"email_accounts_limit": 20,
"email_domains_limit": 3,
"email_messages_limit": 5000,
"broadcasts_limit_per_month": 5000,
"funnels_limit": 10
}
PUT /admin/api/plans/{id}
DELETE /admin/api/plans/{id}
Mail Server
GET /admin/api/mail/stats
GET /admin/api/mail/domains
POST /admin/api/mail/domains → { "name": "example.com", "description": "..." }
DELETE /admin/api/mail/domains/{id}
GET /admin/api/mail/domains/{id}/dns-zone
GET /admin/api/mail/domains/{id}/accounts
2.11 Upload API
Upload & S3 endpoint menggunakan API server (port 5566) dengan Bearer token:
POST /api/upload/image (multipart) → Upload & proses gambar (sharp)
POST /api/upload/file (multipart) → Upload file (PDF, DOC, XLS)
S3
Authorization: Bearer {your_api_token}
POST /api/s3/signed-url → { "fileName": "...", "contentType": "..." }
GET /api/s3/public-url/{fileKey}
GET /api/s3/health