http://127.0.0.1:8899). Tanpa autentikasi — jangan diekspos publik tanpa proteksi.
Tiga jalur capture: job antrean (file tersimpan), preview sinkron (dikembalikan langsung), dan stream query (kompatibel webss).
# 1) PNG full-page, desktop 1280×900
curl -s -X POST localhost:8899/api/preview -H 'Content-Type: application/json' \
-d '{"url":"example.com","mode":"desktop","format":"png","fullPage":true}' -o shot.png
# 2) PDF lewat job antrean (file tersimpan di disk)
curl -s -X POST localhost:8899/api/jobs -H 'Content-Type: application/json' \
-d '{"url":"example.com","mode":"desktop","format":"pdf","fullPage":true}' | jq .job.id
# 3) PDF lewat preview sinkron (langsung dikirim)
curl -s -X POST localhost:8899/api/preview -H 'Content-Type: application/json' \
-d '{"url":"example.com","mode":"desktop","format":"pdf"}' -o page.pdf
# 4) Custom size + JPG lewat query stream
curl -s "localhost:8899/api/screenshot?url=https%3A%2F%2Fexample.com&resX=1440&resY=900&format=jpg&scale=1" -o shot.jpg
| Method | Path | Respons |
|---|---|---|
| POST | /api/jobsMenjalankan capture di belakang antrean. File disimpan di disk; progres bisa dipantau lewat GET /api/jobs/{id}. | JSON `{ job }` (201) |
| POST | /api/previewMenjalankan capture dan mengembalikan file langsung di respons (tanpa menyimpan permanen untuk PNG/JPG). PDF juga didukung dan dikirim sebagai application/pdf. | Binary PNG/JPG/PDF + header `X-Snapshot-*` |
| GET | /api/screenshotSemua parameter lewat query string. `url` wajib di-encode dengan encodeURIComponent. | Binary PNG/JPG/PDF |
| GET | /api/jobsSemua job (terbaru dulu) + status antrean. | JSON `{ jobs, queue, runningJobs, activeCaptures }` |
| GET | /api/jobs/{id}Status, progres, log, statistik, hasil file. | JSON `{ job }` |
| POST | /api/jobs/{id}/cancelJob queued langsung dibatalkan; job running berhenti di checkpoint berikutnya. | JSON `{ job }` |
| DELETE | /api/jobs/{id}Hapus job dari memori sekaligus file hasilnya. | JSON `{ ok: true }` |
| POST | /api/cleanupHapus semua file job & preview tanpa menunggu TTL. | JSON `{ ok, removed, storage }` |
| GET | /api/devicesDaftar preset, batas nilai, dan konfigurasi cleanup. | JSON `{ devices, limits, cleanup }` |
| GET | /healthzAntrean, slot capture aktif, statistik browser bersama, storage, dan konfigurasi cleanup. | JSON status |
| GET | /f/{name}Menyajikan file hasil (png/jpg/pdf) untuk ditampilkan di browser. | File |
| GET | /d/{name}Menyajikan file hasil dengan header attachment. | File (attachment) |
| GET | /openapi.jsonDokumen OpenAPI 3.1 seluruh endpoint — bisa diimpor ke Postman/Insomnia. | JSON |
| GET | /docsDokumentasi interaktif (halaman ini). | HTML |
POST /api/jobs & POST /api/preview| Parameter | Tipe | Default | Keterangan |
|---|---|---|---|
url wajib | string | — | URL target. Tanpa skema otomatis diberi https://. Hanya http/https yang diterima. |
mode | string | desktop | Profil device: desktop, mobile, laptop, desktop4k, iphone, android, tablet, atau custom untuk memakai width/height sendiri. |
width | integer | — | Lebar viewport saat mode: custom. Rentang 100–3840px. |
height | integer | — | Tinggi viewport saat mode: custom. Rentang 100–5000px. |
scaleFactor | integer | 1 (custom) / bawaan preset | Device pixel ratio 1–4. Ukuran file PNG/JPG = width×scaleFactor. |
isMobile | boolean | otomatis (width ≤ 768) | Menandai viewport sebagai mobile (touch + userAgent mobile). Hanya relevan untuk mode: custom. |
theme | string | none | Emulasi prefers-color-scheme: none, light, dark. |
format | string | png (screenshot endpoint: jpg) | Format output: png, jpg, atau pdf. PDF tersedia di semua endpoint. |
quality | integer | 90 | Kualitas kompresi JPG 40–100. Diabaikan untuk PNG/PDF. |
fullPage | boolean | true (screenshot endpoint: false) | Ambil seluruh halaman (auto-scroll dulu) atau hanya viewport. |
delay | integer | 1500 | Jeda tambahan setelah halaman siap, 0–60000 ms. Alias: waitTime. |
retry | integer | 3 | Jumlah percobaan navigasi 1–5 (strategi: networkidle2 → domcontentloaded → load). |
output | string | snapshot | Prefiks nama file (disanitasi). Query di /api/screenshot memakai nama name. |
GET /api/screenshot| Parameter | Tipe | Default | Keterangan |
|---|---|---|---|
url wajib | string | — | URL target. Tanpa skema otomatis diberi https://. Hanya http/https yang diterima. |
mode | string | desktop | Profil device: desktop, mobile, laptop, desktop4k, iphone, android, tablet, atau custom untuk memakai width/height sendiri. |
theme | string | none | Emulasi prefers-color-scheme: none, light, dark. |
format | string | png (screenshot endpoint: jpg) | Format output: png, jpg, atau pdf. PDF tersedia di semua endpoint. |
fullPage | boolean | true (screenshot endpoint: false) | Ambil seluruh halaman (auto-scroll dulu) atau hanya viewport. |
waitTime | integer | — | Alias delay (kompatibel webss). |
output | string | snapshot | Prefiks nama file (disanitasi). Query di /api/screenshot memakai nama name. |
viewport | string | desktop | Preset kompatibel webss: desktop = 1280×900, mobile = 390×844. |
resX | integer | — | Lebar output kompatibel webss (100–3840). Dipakai bersama resY, default skala 1x. |
resY | integer | — | Tinggi output kompatibel webss (100–5000). |
scale | integer | 1 | Device pixel ratio saat memakai resX/resY. Set 1 agar ukuran file persis resX×resY. |
name | string | preview | Alias output untuk /api/screenshot. |
| Key | Label | Viewport |
|---|---|---|
desktop | Desktop | 1280×900 @1x |
mobile | Mobile | 390×844 @3x · touch |
laptop | Laptop | 1920×1080 @1x |
desktop4k | Desktop 4K | 3840×2160 @1x |
iphone | iPhone 15 Pro Max | 430×932 @3x · touch |
android | Android Pixel 8 | 412×915 @3x · touch |
tablet | iPad Pro | 1024×1366 @2x · touch |
custom | Custom size | pakai width × height (100–3840 × 100–5000) |
/api/jobscurl -s -X POST localhost:8899/api/jobs -H 'Content-Type: application/json' \
-d '{"url":"https://news.ycombinator.com","mode":"desktop","format":"pdf","fullPage":true}'/api/previewcurl -s -X POST localhost:8899/api/preview -H 'Content-Type: application/json' \
-d '{"url":"example.com","mode":"custom","width":1440,"height":900,"format":"jpg"}' -o shot.jpg/api/screenshotcurl -s "localhost:8899/api/screenshot?url=https%3A%2F%2Fexample.com&resX=390&resY=844&format=jpg" -o shot.jpg
| Header | Isi |
|---|---|
X-Snapshot-Size | Ukuran file hasil dalam byte |
X-Snapshot-Elapsed | Durasi capture dalam ms |
X-Snapshot-Viewport | Viewport CSS yang dipakai (widthxheight) |
X-Snapshot-Blocked | Jumlah request iklan/tracker yang diblokir |
X-Snapshot-Clipped | 1 bila halaman dipotong karena terlalu tinggi |
X-Snapshot-Browser | reused / launched — apakah browser bersama dipakai ulang |
X-Snapshot-Request-Id | ID permintaan, cocok dengan log server |
| Kode | Arti |
|---|---|
| 400 | Parameter tidak valid (URL kosong, ukuran di luar rentang, format salah) |
| 404 | Job atau file tidak ditemukan |
| 409 | Job sudah selesai/dibatalkan sehingga tidak bisa dibatalkan lagi |
| 413 | PDF hasil lebih besar dari MAX_SYNC_PDF_BYTES pada jalur sinkron — pakai POST /api/jobs |
| 500 | Capture gagal (navigasi error, halaman menolak, renderer crash, render melebihi batas keras) |
| 503 | Antrean penunggu sinkron penuh (MAX_SYNC_WAITERS); respons berisi header Retry-After |
| 504 | Permintaan sinkron melebihi PREVIEW_TIMEOUT_MS |
X-Snapshot-Browser menunjukkan reused).fullPage menjalankan auto-scroll dulu. Halaman lebih tinggi dari MAX_FULLPAGE_HEIGHT (default 32000 px) akan dipotong dan diberi flag X-Snapshot-Clipped: 1.MAX_SYNC_WAITERS, barulah 503 + Retry-After.RENDER_TIMEOUT_MS untuk job, 50 s untuk sinkron), auto-scroll, dan watchdog job (JOB_TIMEOUT_MS). Halaman yang menggantung akan gagal dengan pesan jelas, bukan macet di 90%.FILE_TTL_MINUTES/PREVIEW_TTL_MINUTES, kuota MAX_STORAGE_MB, interval CLEANUP_INTERVAL_MINUTES. Manual lewat POST /api/cleanup.POST /api/jobs (tombol Simpan ke disk di UI).| Variabel | Default | Fungsi |
|---|---|---|
PORT | 8899 | Port HTTP service |
HOST | 0.0.0.0 | Interface bind |
SNAPSHOT_DIR | ./snapshots | Folder output job (dan subfolder preview/) |
MAX_CONCURRENT_CAPTURES | 1 | Jumlah capture bersamaan (job + preview berbagi slot). Alias lama: CONCURRENCY |
MAX_JOBS | 40 | Job yang disimpan di memori/disk sebelum yang terlama dihapus |
MAX_SYNC_WAITERS | 20 | Panjang antrean penunggu permintaan sinkron sebelum 503 |
PREVIEW_TIMEOUT_MS | 55000 | Batas durasi capture sinkron |
MAX_SYNC_HEIGHT | 4000 | Tinggi maksimum (CSS px) untuk PNG/JPG pada jalur sinkron; 0 = tanpa batas |
MAX_SYNC_PDF_BYTES | 41943040 | Ukuran maksimum PDF pada jalur sinkron (byte) |
MAX_FULLPAGE_HEIGHT | 32000 | Tinggi maksimum hasil full-page (CSS px). Lebih tinggi dari ini akan dipotong; 0 = tanpa batas |
JOB_TIMEOUT_MS | 240000 | Watchdog job antrean — job yang lewat batas dihentikan |
RENDER_TIMEOUT_MS | 120000 | Batas keras tahap render PDF/screenshot pada job |
BROWSER_IDLE_MS | 90000 | Tutup Chromium bersama setelah idle selama ini |
CHROME_PATH | auto | Path Chromium (kosong = deteksi otomatis / bundled) |
FILE_TTL_MINUTES | 360 | TTL file job; 0 = nonaktif |
PREVIEW_TTL_MINUTES | 360 | TTL file preview; 0 = nonaktif |
MAX_STORAGE_MB | 1500 | Kuota total folder snapshot; kelebihan dihapus dari yang terlama |
CLEANUP_INTERVAL_MINUTES | 15 | Interval putaran auto cleanup |
PREVIEW_KEEP | 60 | Jumlah file preview terbaru yang dipertahankan sebelum TTL habis |