API Pembuatan Invoice
Buat PDF invoice profesional secara programatis dari server Anda sendiri, cocok untuk sistem internal, marketplace, atau produk SaaS Anda.
1. Autentikasi#
Buat API key di app.invosend.com/settings/api-keys. Workspace harus memakai paket berbayar dan role Anda harus owner.
Kirim key sebagai Bearer token di header Authorization pada setiap request:
Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx403. Key juga ditolak jika workspace masih gratis, suspended, atau expired.2. Endpoint#
Base URL: https://app.invosend.com
Deskripsi API yang bisa dibaca mesin: OpenAPI 3.1 dan Postman collection. Impor salah satunya ke Postman, Insomnia, atau generator SDK.
3. Request Body#
Contoh request lengkap:
curl -X POST https://app.invosend.com/api/invoices/generate-external \
-H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"items": [
{ "description": "Consulting Services", "quantity": 2, "price": 500000, "tax_rate": 11 }
],
"discount_total": 50000,
"currency": "IDR",
"notes": "Thank you for your business."
}'Contoh invoice recurring (invoice pertama sekarang, lalu satu setiap bulan, total 6):
curl -X POST https://app.invosend.com/api/invoices/generate-external \
-H "Authorization: Bearer isk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"items": [
{ "description": "Monthly retainer", "quantity": 1, "price": 2500000 }
],
"currency": "IDR",
"recurring_interval": "monthly",
"recurring_count": 6
}'Idempotency-Key (1-255 karakter, misalnya UUID yang Anda buat untuk setiap invoice). Jika request pertama berhasil, pengulangan mengembalikan respons yang sama dengan header Idempotent-Replayed: true, tanpa membuat invoice lagi atau memakai kredit lagi (credits_remaining adalah nilai dari panggilan pertama). Key disimpan 24 jam per workspace. Hanya respons sukses yang disimpan, jadi request yang gagal bisa diulang dengan key yang sama.4. Response#
200 OK berarti invoice berhasil dibuat dan PDF sudah digenerate:
{
"data": {
"id": "cjld2cjxh0000qzrmn831i7rn",
"invoice_number": "INV-1-202609-0016",
"pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202609_0016_UNPAID_0da2beeabb.pdf",
"credits_remaining": 24,
"is_recurring": false,
"template": {
"id": "k3p9x2m7c0000abcd1234efgh",
"name": "Classic",
"source": "system_default"
}
}
}credits_remaining bernilai null jika workspace memakai kuota unlimited. id dipakai untuk memanggil Endpoint Tambahan di bawah. Invoice dari API juga muncul di daftar invoice workspace dan memakai urutan nomor yang sama dengan invoice manual. Nomor invoice berbentuk INV-{id workspace}-{YYYYMM}-{urutan}. Untuk invoice recurring, respons juga berisi objek recurring: schedule_id, interval, occurrences, next_issue_date, end_date. recurring.schedule_id adalah id yang dipakai pada endpoint recurring di bawah.5. Kode Error#
6. Rate Limit#
X-RateLimit-Limit dan X-RateLimit-Remaining. Kuota API workspace dikonfigurasi berdasarkan paket membership Invosend. Butuh volume produksi lebih besar? Hubungi kami dari akun workspace Anda. Key yang sudah dicabut tidak dihitung dalam batas jumlah key.7. Endpoint Tambahan#
API key yang sama juga bisa dipakai membaca dan mengelola invoice yang dibuat lewat generate-external:
payment_gateway (dan opsional payment_account) pada generate-external, lalu kirim ke pelanggan halaman pembayaran publik invoice: https://app.invosend.com/p/invoice/{id}, dengan id yang dikembalikan API. Pelanggan membayar di sana lewat gateway yang terhubung dan invoice otomatis ditandai lunas. Checkout ditangani halaman itu; tidak ada endpoint checkout publik terpisah yang perlu dipanggil.8. Webhook#
Tanpa perlu polling, daftarkan URL HTTPS dan Invosend akan mengirim request POST berisi JSON setiap kali ada perubahan pada invoice. Tambahkan endpoint di Pengaturan > Webhooks (pemilik workspace, paket dengan akses API, maksimal 5 endpoint). Setiap endpoint punya secret penandatanganan sendiri yang hanya ditampilkan sekali.
Event dikirim untuk invoice yang dibuat di dashboard maupun lewat API ini. Template invoice berulang tidak pernah dikirim.
Setiap event memakai amplop yang sama. data.object adalah invoice dengan bentuk yang sama seperti GET /api/invoices/external/:id; event perubahan status juga menyertakan data.previous_status:
{
"id": "evt_9f2c1b7a4e3d5c6b8a1f0e2d",
"object": "event",
"type": "invoice.paid",
"created": "2026-10-01T09:30:12.000Z",
"data": {
"object": {
"id": "cjld2cjxh0000qzrmn831i7rn",
"invoice_number": "INV-1-202610-0007",
"customer_name": "Acme Corp",
"customer_email": "billing@acme.com",
"currency": "USD",
"subtotal": 500,
"discount_total": 0,
"tax_rate": 0,
"tax_amount": 0,
"amount": 500,
"amount_paid": 500,
"amount_credited": 0,
"amount_received": 500,
"invoice_status": "paid",
"is_archived": false,
"is_recurring": false,
"recurring_interval": "none",
"issue_date": "2026-10-01T02:15:40.000Z",
"due_date": "2026-10-15",
"paid_at": "2026-10-01T09:30:11.000Z",
"pdf_url": "https://cdn.invosend.com/company/1/pdf/Invoice_INV_1_202610_0007_PAID.pdf",
"pdf_status": "ready"
},
"previous_status": "unpaid"
}
}Setiap request membawa header berikut. Untuk memverifikasinya, hitung HMAC-SHA256 dari {t}.{body mentah} dengan secret endpoint lalu bandingkan dengan v1; tolak bila t lebih lama dari 5 menit:
POST /your/webhook/url
Content-Type: application/json
Invosend-Event: invoice.paid
Invosend-Delivery: evt_9f2c1b7a4e3d5c6b8a1f0e2d
Invosend-Signature: t=1790847012,v1=5b1d...e9a2
// Node.js
import crypto from "crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(parts.t + "." + rawBody)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}2xx apa pun dalam 10 detik. Selain itu akan dicoba lagi hingga 7 kali (setelah 1 menit, 5 menit, 30 menit, 2 jam, 6 jam, 12 jam, dan 24 jam). Endpoint yang terus gagal akan dimatikan dan Anda diberi notifikasi. Event bisa datang lebih dari sekali atau tidak berurutan: gunakan id event untuk mengabaikan duplikat dan anggap invoice_status sebagai sumber kebenaran. Log pengiriman disimpan 30 hari, dan event mana pun bisa dikirim ulang dari Pengaturan > Webhooks.9. Batasan#
API ini sengaja dibatasi untuk pembuatan invoice dan pengelolaan ringan. Berikut yang belum tersedia:
- Webhook hanya mencakup invoice dibuat, dibayar, jatuh tempo, dan dibatalkan. Perubahan lain, seperti edit atau pengarsipan, tidak dikirim: baca kondisi terbaru dengan
GET /invoices/external/:id. - Invoice yang dibuat tiap request tidak dikirim lewat email: API ini hanya men-generate PDF, jadi mengirimkannya ke pelanggan jadi tanggung jawab Anda (atau pakai dashboard). Pengecualian: rangkaian recurring, di mana setiap invoice lanjutan yang dibuat penjadwal dikirim otomatis ke
customer_email. - Invoice tidak bisa diedit setelah dibuat — hanya status dan status arsipnya yang bisa diubah lewat API ini.
- Payment gateway harus sudah terhubung di dashboard lebih dulu; API ini hanya melampirkannya ke invoice, tidak menghubungkan gateway itu sendiri.
- Rangkaian recurring bisa dijeda, dilanjutkan, diperpanjang, diubah jadwalnya, dan kemunculan mendatangnya dilewati lewat API, tetapi isinya (item, pelanggan, nominal) tidak bisa diedit dan rangkaian tidak bisa dihapus lewat API; lakukan itu di dashboard.
Pertanyaan Umum#
Bagaimana cara mendapatkan API key Invosend?
Buat akun di app.invosend.com, upgrade workspace ke paket berbayar, lalu buka Settings > API Keys dan klik Generate key. Key asli hanya ditampilkan sekali saat dibuat.
Berapa biaya setiap panggilan API generate invoice?
Setiap request berhasil akan mengurangi 1 kredit invoice dari saldo workspace Anda. Kreditnya sama dengan kredit invoice yang dibuat lewat dashboard.
Berapa rate limit API ini?
Rate limit workspace mengikuti konfigurasi paket berbayar Anda. Bagian Rate Limit di atas memuat batas terbaru untuk setiap paket.