{"openapi":"3.1.0","info":{"title":"WebSnap API","version":"1.1.0","description":"Screenshot & PDF halaman web: preset device + custom size, ad/tracker blocking, auto-scroll, auto cleanup disk."},"servers":[{"url":"/"}],"paths":{"/api/jobs":{"post":{"summary":"Buat job antrean","tags":["capture"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL target (wajib)"},"mode":{"type":"string","enum":["desktop","mobile","laptop","desktop4k","iphone","android","tablet","custom"],"default":"desktop"},"theme":{"type":"string","enum":["none","light","dark"],"default":"none"},"format":{"type":"string","enum":["png","jpg","pdf"],"default":"png"},"quality":{"type":"integer","minimum":40,"maximum":100,"default":90},"fullPage":{"type":"boolean","default":true},"delay":{"type":"integer","minimum":0,"maximum":60000,"default":1500},"retry":{"type":"integer","minimum":1,"maximum":5,"default":3},"output":{"type":"string","default":"snapshot"},"width":{"type":"integer","minimum":100,"maximum":3840},"height":{"type":"integer","minimum":100,"maximum":5000},"scaleFactor":{"type":"integer","minimum":1,"maximum":4},"isMobile":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Job dibuat","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"integer"},"status":{"type":"string","enum":["queued","running","done","error","cancelled"]},"progress":{"type":"integer","minimum":0,"maximum":100},"stage":{"type":"string"},"options":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL target (wajib)"},"mode":{"type":"string","enum":["desktop","mobile","laptop","desktop4k","iphone","android","tablet","custom"],"default":"desktop"},"theme":{"type":"string","enum":["none","light","dark"],"default":"none"},"format":{"type":"string","enum":["png","jpg","pdf"],"default":"png"},"quality":{"type":"integer","minimum":40,"maximum":100,"default":90},"fullPage":{"type":"boolean","default":true},"delay":{"type":"integer","minimum":0,"maximum":60000,"default":1500},"retry":{"type":"integer","minimum":1,"maximum":5,"default":3},"output":{"type":"string","default":"snapshot"},"width":{"type":"integer","minimum":100,"maximum":3840},"height":{"type":"integer","minimum":100,"maximum":5000},"scaleFactor":{"type":"integer","minimum":1,"maximum":4},"isMobile":{"type":"boolean"}}},"fileUrl":{"type":"string"},"downloadUrl":{"type":"string"},"sizeBytes":{"type":"integer"},"elapsedMs":{"type":"integer"},"clipped":{"type":"boolean"},"error":{"type":"string"},"logs":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"string"},"level":{"type":"string","enum":["info","success","warn","error"]},"message":{"type":"string"}}}}}}}}}}},"400":{"description":"Parameter tidak valid"}}},"get":{"summary":"Daftar job","tags":["jobs"],"responses":{"200":{"description":"Daftar job"}}}},"/api/preview":{"post":{"summary":"Preview langsung (sinkron, PNG/JPG/PDF)","tags":["capture"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL target (wajib)"},"mode":{"type":"string","enum":["desktop","mobile","laptop","desktop4k","iphone","android","tablet","custom"],"default":"desktop"},"theme":{"type":"string","enum":["none","light","dark"],"default":"none"},"format":{"type":"string","enum":["png","jpg","pdf"],"default":"png"},"quality":{"type":"integer","minimum":40,"maximum":100,"default":90},"fullPage":{"type":"boolean","default":true},"delay":{"type":"integer","minimum":0,"maximum":60000,"default":1500},"retry":{"type":"integer","minimum":1,"maximum":5,"default":3},"output":{"type":"string","default":"preview"},"width":{"type":"integer","minimum":100,"maximum":3840},"height":{"type":"integer","minimum":100,"maximum":5000},"scaleFactor":{"type":"integer","minimum":1,"maximum":4},"isMobile":{"type":"boolean"}}}}}},"responses":{"200":{"description":"File hasil","headers":{"X-Snapshot-Size":{"description":"Ukuran file hasil dalam byte","schema":{"type":"string"}},"X-Snapshot-Elapsed":{"description":"Durasi capture dalam ms","schema":{"type":"string"}},"X-Snapshot-Viewport":{"description":"Viewport CSS yang dipakai (widthxheight)","schema":{"type":"string"}},"X-Snapshot-Blocked":{"description":"Jumlah request iklan/tracker yang diblokir","schema":{"type":"string"}},"X-Snapshot-Clipped":{"description":"1 bila halaman dipotong karena terlalu tinggi","schema":{"type":"string"}},"X-Snapshot-Browser":{"description":"reused / launched — apakah browser bersama dipakai ulang","schema":{"type":"string"}},"X-Snapshot-Request-Id":{"description":"ID permintaan, cocok dengan log server","schema":{"type":"string"}}}},"400":{"description":"Parameter tidak valid"},"503":{"description":"Slot capture penuh"},"504":{"description":"Melebihi PREVIEW_TIMEOUT_MS"}}}},"/api/screenshot":{"get":{"summary":"Stream langsung (kompatibel webss)","tags":["capture"],"parameters":[{"name":"url","in":"query","required":true,"description":"URL target. Tanpa skema otomatis diberi `https://`. Hanya http/https yang diterima.","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"Profil device: desktop, mobile, laptop, desktop4k, iphone, android, tablet, atau `custom` untuk memakai width/height sendiri.","schema":{"type":"string"}},{"name":"theme","in":"query","required":false,"description":"Emulasi `prefers-color-scheme`: `none`, `light`, `dark`.","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"Format output: `png`, `jpg`, atau `pdf`. PDF tersedia di semua endpoint.","schema":{"type":"string"}},{"name":"fullPage","in":"query","required":false,"description":"Ambil seluruh halaman (auto-scroll dulu) atau hanya viewport.","schema":{"type":"string"}},{"name":"waitTime","in":"query","required":false,"description":"Alias `delay` (kompatibel webss).","schema":{"type":"integer"}},{"name":"output","in":"query","required":false,"description":"Prefiks nama file (disanitasi). Query di `/api/screenshot` memakai nama `name`.","schema":{"type":"string"}},{"name":"viewport","in":"query","required":false,"description":"Preset kompatibel webss: `desktop` = 1280×900, `mobile` = 390×844.","schema":{"type":"string"}},{"name":"resX","in":"query","required":false,"description":"Lebar output kompatibel webss (100–3840). Dipakai bersama `resY`, default skala 1x.","schema":{"type":"integer"}},{"name":"resY","in":"query","required":false,"description":"Tinggi output kompatibel webss (100–5000).","schema":{"type":"integer"}},{"name":"scale","in":"query","required":false,"description":"Device pixel ratio saat memakai `resX`/`resY`. Set 1 agar ukuran file persis resX×resY.","schema":{"type":"integer"}},{"name":"name","in":"query","required":false,"description":"Alias `output` untuk `/api/screenshot`.","schema":{"type":"string"}}],"responses":{"200":{"description":"File hasil"},"400":{"description":"Parameter tidak valid"}}}},"/api/jobs/{id}":{"get":{"summary":"Detail job","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Detail job"},"404":{"description":"Tidak ditemukan"}}},"delete":{"summary":"Hapus job + file","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Terhapus"}}}},"/api/jobs/{id}/cancel":{"post":{"summary":"Batalkan job","tags":["jobs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dibatalkan"},"409":{"description":"Job sudah final"}}}},"/api/cleanup":{"post":{"summary":"Bersihkan disk sekarang","tags":["maintenance"],"responses":{"200":{"description":"Hasil cleanup"}}}},"/api/devices":{"get":{"summary":"Profil device & limits","tags":["info"],"responses":{"200":{"description":"Daftar preset"}}}},"/healthz":{"get":{"summary":"Kesehatan service","tags":["info"],"responses":{"200":{"description":"Status"}}}},"/f/{name}":{"get":{"summary":"Preview file inline","tags":["files"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File"},"404":{"description":"Tidak ditemukan"}}}},"/d/{name}":{"get":{"summary":"Download file","tags":["files"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File"},"404":{"description":"Tidak ditemukan"}}}}},"components":{"schemas":{"Job":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"integer"},"status":{"type":"string","enum":["queued","running","done","error","cancelled"]},"progress":{"type":"integer","minimum":0,"maximum":100},"stage":{"type":"string"},"options":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"URL target (wajib)"},"mode":{"type":"string","enum":["desktop","mobile","laptop","desktop4k","iphone","android","tablet","custom"],"default":"desktop"},"theme":{"type":"string","enum":["none","light","dark"],"default":"none"},"format":{"type":"string","enum":["png","jpg","pdf"],"default":"png"},"quality":{"type":"integer","minimum":40,"maximum":100,"default":90},"fullPage":{"type":"boolean","default":true},"delay":{"type":"integer","minimum":0,"maximum":60000,"default":1500},"retry":{"type":"integer","minimum":1,"maximum":5,"default":3},"output":{"type":"string","default":"snapshot"},"width":{"type":"integer","minimum":100,"maximum":3840},"height":{"type":"integer","minimum":100,"maximum":5000},"scaleFactor":{"type":"integer","minimum":1,"maximum":4},"isMobile":{"type":"boolean"}}},"fileUrl":{"type":"string"},"downloadUrl":{"type":"string"},"sizeBytes":{"type":"integer"},"elapsedMs":{"type":"integer"},"clipped":{"type":"boolean"},"error":{"type":"string"},"logs":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"string"},"level":{"type":"string","enum":["info","success","warn","error"]},"message":{"type":"string"}}}}}}}},"tags":[{"name":"capture","description":"Menjalankan capture"},{"name":"jobs","description":"Manajemen antrean"},{"name":"files","description":"Menyajikan hasil"},{"name":"maintenance","description":"Cleanup disk"},{"name":"info","description":"Status & konfigurasi"}]}