Dokumentasi API & webhook
Buat flipbook otomatis dari sistem Anda dengan API anflip, dan terima webhook saat flipbook siap, konversi gagal, atau ada lead baru.
Terakhir diperbarui 29 September 2026
API anflip dipakai untuk membuat dan mengelola flipbook langsung dari sistem Anda, misalnya CMS, toko online, atau aplikasi internal, tanpa upload manual lewat dashboard. Webhook adalah kebalikannya: anflip yang memberi tahu sistem Anda saat sesuatu terjadi.
API tersedia di semua paket. Batas ukuran file, jumlah halaman, jumlah flipbook, dan penyimpanan mengikuti paket tim pemilik API key.
Kapan dipakai
- Katalog yang sering berubah. Sistem toko membuat PDF katalog harga terbaru tiap minggu dan mengirimnya ke anflip lewat API. Tautan flipbook dipasang otomatis di website.
- Terbitan rutin. Majalah, buletin, atau laporan bulanan langsung menjadi flipbook begitu PDF final selesai. Webhook
flipbook.readymemberi tahu sistem Anda untuk mempublikasikan tautannya. - Lead langsung ke tim sales. Webhook
lead.createdmengirim isian form lead pembaca ke CRM, WhatsApp, atau Telegram sales dalam hitungan detik. - Banyak klien. Agensi membuat dan mengelola flipbook puluhan klien dari sistem internalnya.
Mulai cepat
- Buka Dashboard → API, isi nama key (misalnya "Integrasi toko online"), lalu klik Buat key. Salin key yang muncul. Key hanya ditampilkan sekali.
- Upload PDF pertama Anda:
curl -X POST https://manage.anflip.id/api/v1/ext/flipbooks \
-H "Authorization: Bearer afl_xxxxxxxxxxxxxxxx" \
-H "Accept: application/json" \
-F "file=@katalog.pdf" \
-F "title=Katalog Oktober" \
-F "visibility=unlisted"
- Tunggu konversi selesai lewat webhook
flipbook.readyatau dengan mengecekGET /flipbooks/{id}, lalu bagikanpublic_url.
Autentikasi & aturan umum
Kirim API key di header setiap request:
Authorization: Bearer afl_xxxxxxxxxxxxxxxx
Accept: application/json
| Hal | Nilai |
|---|---|
| Base URL | https://manage.anflip.id/api/v1/ext |
| Format | JSON, kecuali upload file (multipart/form-data) |
| Batas request | 60 request per menit per key. Lebih dari itu dijawab 429 |
| Bahasa pesan error | Indonesia. Tambahkan Accept-Language: en untuk bahasa Inggris |
| Jumlah key | Maksimal 10 per tim |
| Pemilik | Flipbook dibuat di tim pemilik key, atas nama anggota yang membuat key |
.env atau secret manager). Jangan pernah menaruhnya di kode yang berjalan di browser atau aplikasi mobile, karena siapa pun bisa membacanya. Bila key bocor, hapus di Dashboard → API lalu buat key baru.Objek flipbook
Semua endpoint menjawab flipbook dalam bentuk ini (di dalam data):
{
"id": "01J9Z6K3Q4T8V2N5M7P0R1S3W4",
"title": "Katalog Oktober",
"slug": "5f2a9c01be",
"status": "ready",
"visibility": "unlisted",
"page_count": 24,
"progress": 100,
"converting": false,
"has_live_version": true,
"has_password": false,
"allow_download": false,
"error": null,
"cover_url": "https://cdn.anflip.id/fb/01J9…/v1/p1-md.webp",
"public_url": "https://anflip.id/flip-book/5f2a9c01be",
"storage_bytes": 5241880,
"created_at": "2026-10-01T02:00:00+00:00",
"processed_at": "2026-10-01T02:00:41+00:00",
"published_at": "2026-10-01T02:00:00+00:00"
}
| Field | Arti |
|---|---|
status | queued (menunggu antrean), processing (dikonversi), ready, atau failed |
progress | Persentase konversi, 0–100 |
has_live_version | true bila sudah ada halaman yang bisa dibaca. Pakai ini, bukan status, untuk tahu flipbook siap dibagikan |
converting | true selama konversi berjalan (termasuk saat PDF sedang diganti) |
visibility | private (hanya tim), unlisted (siapa pun yang punya tautan, tidak diindeks Google), public |
public_url | Tautan untuk pembaca |
error | Alasan gagal bila status = failed, misalnya PDF rusak atau terkunci kata sandi |
Endpoint
Membuat flipbook
POST /flipbooks, dikirim sebagai multipart/form-data. Konversi berjalan di latar belakang, jadi respons langsung datang dengan status 202 dan status: "queued".
| Field | Wajib | Keterangan |
|---|---|---|
file | ya | File PDF. Ukuran maksimal mengikuti paket tim |
title | tidak | Judul. Bila kosong, diambil dari nama file |
visibility | tidak | private (bawaan), unlisted, atau public. Untuk unlisted dan public, pembuat key harus sudah memverifikasi email |
Daftar flipbook
GET /flipbooks menjawab 50 flipbook terbaru per halaman. Pakai ?page=2 untuk halaman berikutnya. Informasi halaman ada di meta (current_page, last_page, total).
Detail flipbook
GET /flipbooks/{id} menjawab satu flipbook. Cocok untuk mengecek status konversi.
Menghapus flipbook
DELETE /flipbooks/{id}. Tautan flipbook langsung berhenti bekerja. Respons: { "data": { "id": "…", "deleted": true } }.
Menunggu konversi selesai
PDF 20–50 halaman biasanya selesai dalam 1 menit; PDF ratusan halaman bisa beberapa menit. Ada dua cara menunggunya:
- Webhook
flipbook.ready(disarankan). Tidak perlu bertanya berulang-ulang; anflip yang memberi tahu begitu selesai. - Polling. Cek
GET /flipbooks/{id}tiap 5–10 detik sampaihas_live_versionbernilaitrueataustatusbernilaifailed.
async function waitUntilReady(id) {
for (;;) {
const res = await fetch(`https://manage.anflip.id/api/v1/ext/flipbooks/${id}`, {
headers: { Authorization: `Bearer ${process.env.ANFLIP_KEY}`, Accept: "application/json" },
});
const { data } = await res.json();
if (data.has_live_version) return data.public_url;
if (data.status === "failed") throw new Error(data.error);
await new Promise((r) => setTimeout(r, 8000));
}
}
Kode error
| Status | Arti | Yang perlu dilakukan |
|---|---|---|
401 | API key salah, dihapus, atau tidak dikirim | Cek header Authorization |
403 | Tidak diizinkan, misalnya publikasi oleh pembuat key yang emailnya belum terverifikasi | Baca message |
404 | Flipbook tidak ada atau milik tim lain | Cek id |
422 | Isian tidak valid: bukan PDF, file terlalu besar, atau kuota paket penuh | Detail per field ada di errors |
429 | Lebih dari 60 request per menit | Tunggu sebentar lalu ulangi |
5xx | Gangguan di sisi anflip | Ulangi beberapa saat lagi |
Contoh respons 422:
{
"message": "Paket Anda mengizinkan 5 flipbook. Hapus yang lama atau upgrade paket.",
"errors": { "file": ["Paket Anda mengizinkan 5 flipbook. Hapus yang lama atau upgrade paket."] }
}
Webhook
Mendaftarkan webhook
Di Dashboard → API → Webhook:
- Isi URL di sistem Anda. URL harus
https://dan bisa diakses dari internet (bukanlocalhostatau IP jaringan lokal). - Pilih event yang ingin diterima, lalu klik Tambah webhook.
- Salin signing secret (berawalan
whsec_) yang muncul. Nilai ini hanya ditampilkan sekali dan dipakai untuk memverifikasi kiriman. - Kirim ping untuk mencoba. Status kiriman terakhir tampil di daftar webhook.
Maksimal 5 webhook per tim.
Event
| Event | Kapan dikirim | Isi data |
|---|---|---|
flipbook.ready | Konversi selesai, termasuk setelah PDF diganti | Objek flipbook lengkap |
flipbook.failed | Konversi gagal | id, title, error (selalu dalam bahasa Inggris) |
lead.created | Pembaca mengisi form lead di flipbook | id, flipbook (id, title, url), data (isian), created_at |
ping | Anda menekan tombol ping di dashboard | team |
Isian lead.created hanya berisi kolom yang dipakai di form: name, email, phone, company, dan message.
Bentuk kiriman
anflip mengirim POST dengan body JSON seperti ini:
{
"id": "evt_01J9Z7A2B3C4D5E6F7G8H9J0K1",
"event": "lead.created",
"created_at": "2026-10-01T03:30:00+00:00",
"data": {
"id": 128,
"flipbook": { "id": "01J9Z6K3Q4T8V2N5M7P0R1S3W4", "title": "Katalog Oktober", "url": "https://anflip.id/flip-book/5f2a9c01be" },
"data": { "name": "Sari", "email": "sari@example.com", "phone": "081234567890" },
"created_at": "2026-10-01T03:30:00+00:00"
}
}
Header yang ikut dikirim:
| Header | Isi |
|---|---|
Content-Type | application/json |
X-Anflip-Event | Nama event, misalnya lead.created |
X-Anflip-Signature | sha256= diikuti HMAC-SHA256 dari body mentah, memakai signing secret |
User-Agent | anflip-webhooks/1.0 |
Memverifikasi tanda tangan
Selalu cek tanda tangan sebelum memproses, supaya kiriman palsu tidak diterima. Hitung HMAC dari body mentah (persis seperti diterima, sebelum di-parse menjadi JSON).
// Node.js (Express): app.post("/anflip-webhook", express.raw({ type: "application/json" }), handler)
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(header ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// PHP / Laravel
$expected = 'sha256='.hash_hmac('sha256', $request->getContent(), env('ANFLIP_WEBHOOK_SECRET'));
abort_unless(hash_equals($expected, (string) $request->header('X-Anflip-Signature')), 401);
# Python (Flask)
import hashlib, hmac
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Balasan, pengulangan, dan praktik terbaik
- Balas
2xxdalam 10 detik. Simpan kiriman lalu proses di latar belakang (antrean). Jangan menunggu proses panjang sebelum membalas. - Kiriman yang gagal diulang (bukan
2xx, timeout, atau tidak bisa terhubung) hingga total 5 kali, dengan jeda 10 detik, 1 menit, 5 menit, lalu 30 menit. - Tangani duplikat. Karena ada pengulangan, event yang sama bisa datang lebih dari sekali. Simpan
idevent (evt_…) dan abaikan yang sudah pernah diproses. - Urutan tidak dijamin. Bila urutan penting, pakai
created_at. - Redirect tidak diikuti. Daftarkan URL akhir yang benar, bukan URL yang dialihkan.
Contoh lengkap: katalog mingguan
Sistem toko membuat katalog.pdf tiap Senin, mengirimnya ke anflip, lalu memasang tautannya di website begitu siap.
// Laravel: dijalankan scheduler tiap Senin
$response = Http::withToken(env('ANFLIP_KEY'))->acceptJson()
->attach('file', file_get_contents(storage_path('katalog.pdf')), 'katalog.pdf')
->post('https://manage.anflip.id/api/v1/ext/flipbooks', [
'title' => 'Katalog '.now()->translatedFormat('j F Y'),
'visibility' => 'unlisted',
])->throw();
Setting::put('katalog_pending', $response->json('data.id'));
// Route webhook: POST /anflip-webhook
$expected = 'sha256='.hash_hmac('sha256', $request->getContent(), env('ANFLIP_WEBHOOK_SECRET'));
abort_unless(hash_equals($expected, (string) $request->header('X-Anflip-Signature')), 401);
if ($request->input('event') === 'flipbook.ready'
&& $request->input('data.id') === Setting::get('katalog_pending')) {
Setting::put('katalog_url', $request->input('data.public_url')); // tampil di website
}
return response()->noContent();
Tanpa kode
- Google Sheets dan Mailchimp bisa dihubungkan langsung di Dashboard → Integrasi, tanpa API.
- Aplikasi lain (CRM, Slack, email, WhatsApp gateway): sambungkan webhook ke Zapier, Make, atau n8n memakai trigger "Catch webhook" / "Webhooks", lalu teruskan ke aplikasi tujuan.