Pemindaian API
Pemindaian API mengubah PDF menjadi hasil pindaian yang meyakinkan lewat satu panggilan REST, cocok untuk alur otomatis dan integrasi aplikasi. Buat tugas, unggah PDF, lalu jajaki statusnya atau tunggu webhook: tiga langkah, dari lingkungan atau bahasa apa pun yang bisa mengirim permintaan HTTP. Ruang warna, resolusi, rotasi, kekaburan, derau, kecerahan, kontras, dan batas semuanya bisa diatur.
Bagaimana satu panggilan berjalan
Buat tugasnya
POST /v1/scan-jobs
Kirim config Anda dan, bila perlu, webhookUrl; Anda menerima jobID dan uploadURL yang sudah ditandatangani.
Unggah PDF
PUT {uploadURL}
Lakukan PUT file langsung ke alamat S3 bertanda tangan dari langkah sebelumnya — tanpa token.
Ambil hasil pindaian
GET /v1/scan-jobs/{jobID}
Jajaki statusnya atau tunggu webhook; begitu tugas berstatus completed, unduh lewat downloadURL.
Cocok untuk hal ini
Produksi massal di backend
Kontrak, faktur, dan laporan yang dibuat di server langsung melewati efek pemindaian, tanpa ada yang mengulangi prosesnya secara manual di halaman web.
Di dalam sistem yang sudah ada
Tambahkan tindakan «ekspor hasil pindaian» pada CRM, ERP, atau sistem tiket, lalu biarkan ia memanggil API.
Rantai otomatisasi
CI, n8n, Zapier, dan sejenisnya memulai tugas berdasarkan peristiwa, dan webhook menyerahkannya ke langkah berikutnya setelah selesai.
Antrean file yang besar
Tugas bersifat asinkron: setelah dibuat, masing-masing diproses sendiri, dan kemajuannya bisa dilihat lewat status dan createdAfter.
Bahasa dan lingkungan
API ini hanya HTTP dan JSON biasa, jadi bahasa atau platform otomatisasi apa pun yang bisa mengirim permintaan dapat memanggilnya.
Contoh kode
Add Look Scanned API Scan to this project, so I can turn a PDF into a
realistic scanned copy from code.
API docs: https://lookscanned.io/en/scan/api
Write one function that:
1. POST https://api.lookscanned.io/v1/scan-jobs
Header: Authorization: Bearer $LOOKSCANNED_API_TOKEN
Body: {"config": {"colorspace": "gray", "resolution": 150, "rotate": 1}}
It returns jobID and a presigned uploadURL.
2. PUT the PDF bytes to uploadURL with Content-Type: application/pdf.
Send no Authorization header — that URL is already signed.
3. Poll GET /v1/scan-jobs/{jobID} until status is "completed" (or "failed"),
then return downloadURL.
Read the token from the LOOKSCANNED_API_TOKEN environment variable. Use the
language and HTTP client this project already uses, and add one test.interface ScanConfig {
rotate?: number // degrees to rotate the document
rotate_var?: number // degrees to rotate the document randomly
colorspace?: 'gray' | 'sRGB' // the colorspace of the output image
blur?: number // the amount of blur to apply to the image
noise?: number // the amount of noise to apply to the image
border?: boolean // whether to add a border to the image
brightness?: number // the brightness of the image. 1 is no change
contrast?: number // the contrast of the image. 1 is no change
resolution?: number // the resolution of the image in DPI
output_format?: 'image/png' | 'image/jpeg' // the format of the output image
}
interface ScanOptions {
config: ScanConfig
webhookUrl?: string // webhook URL to notify when job is completed
}
interface ScanResponse {
jobID: string // UUID of the scan job
userID: string // UUID of the user who created the job
createdAt: number // timestamp of job creation
status: 'pending' | 'processing' | 'completed' | 'failed'
config: ScanConfig
inputUploadedAt?: number // timestamp when input file was uploaded
completedAt?: number // timestamp when job was completed
webhookUrl?: string // webhook URL for notifications
uploadURL?: string // S3 presigned URL for file upload
downloadURL?: string // S3 presigned URL for file download
}
async function apiScan(pdfBlob: Blob, scanOptions: ScanOptions, token: string): Promise<ScanResponse> {
const response = await fetch('https://api.lookscanned.io/v1/scan-jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: JSON.stringify(scanOptions)
})
const result: ScanResponse = await response.json()
// PUT PDF Blob to upload URL
const uploadURL = result.uploadURL
await fetch(uploadURL, {
method: 'PUT',
headers: {
'Content-Type': 'application/pdf',
'Content-Length': pdfBlob.size.toString()
},
body: pdfBlob
})
// get scan job status
const jobStatusResponse = await fetch(`https://api.lookscanned.io/v1/scan-jobs/${result.jobID}`, {
headers: {
'Authorization': `Bearer ${token}`
}
})
return await jobStatusResponse.json()
}import requests
def api_scan(pdf_file, scan_options, token):
# Create scan job
response = requests.post(
'https://api.lookscanned.io/v1/scan-jobs',
headers={'Authorization': f'Bearer {token}'},
json=scan_options
)
result = response.json()
# Upload PDF to presigned URL
upload_url = result['uploadURL']
requests.put(
upload_url,
headers={
'Content-Type': 'application/pdf',
'Content-Length': str(len(pdf_file))
},
data=pdf_file
)
# Get scan job status
job_status = requests.get(
f'https://api.lookscanned.io/v1/scan-jobs/{result["jobID"]}',
headers={'Authorization': f'Bearer {token}'}
)
return job_status.json()
# Example usage
if __name__ == "__main__":
with open('document.pdf', 'rb') as f:
pdf_content = f.read()
options = {
'config': {
# Optional parameters:
# 'rotate': 0, # degrees to rotate the document
# 'colorspace': 'gray', # gray or sRGB
# 'resolution': 300, # DPI
# 'rotate_var': 0, # random rotation variance in degrees
# 'blur': 0, # amount of blur
# 'noise': 0, # amount of noise
# 'border': False, # whether to add border
# 'brightness': 1, # 1 is no change
# 'contrast': 1, # 1 is no change
# 'output_format': 'image/png' # image/png or image/jpeg
},
'webhookUrl': 'https://example.com/webhook'
}
result = api_scan(pdf_content, options, 'your-api-token')
print(f"Scan job created with ID: {result['jobID']}")# Set your API token and PDF file as environment variables
export LOOKSCANNED_API_TOKEN='your_api_token_here'
# Create a new scan job
curl -X POST 'https://api.lookscanned.io/v1/scan-jobs' \
-H "Authorization: Bearer ${LOOKSCANNED_API_TOKEN}" \
-H 'Content-Type: application/json' \
-d '{
"config": {
"rotate": 0,
"rotate_var": 1,
"colorspace": "gray",
"blur": 0.2,
"noise": 0.1,
"border": true,
"brightness": 1.0,
"contrast": 1.0,
"resolution": 300,
"output_format": "image/jpeg"
},
"webhookUrl": "https://your-domain.com/webhook"
}'
# Response will include uploadURL and jobID
# {
# "jobID": "550e8400-e29b-41d4-a716-446655440000",
# "userID": "446655440000-e29b-41d4-a716-550e8400",
# "createdAt": 1616161616,
# "status": "created",
# "uploadURL": "...",
# "config": { ... }
# }
# Upload PDF file to the presigned URL
curl -X PUT 'PRESIGNED_UPLOAD_URL' \
-H 'Content-Type: application/pdf' \
-H "Content-Length: PDF_FILE_SIZE" \
--data-binary "@path/to/your/file.pdf"
# Check job status
curl 'https://api.lookscanned.io/v1/scan-jobs/JOB_ID' \
-H "Authorization: Bearer ${LOOKSCANNED_API_TOKEN}"
# Response will include status and downloadURL when completed
# {
# "jobID": "550e8400-e29b-41d4-a716-446655440000",
# "status": "completed",
# "downloadURL": "...",
# ...
# }
# Download the PDF
curl -o scanned.pdf 'DOWNLOAD_URL'API Bearer Token
Token melekat pada akun Anda dan bisa dibuat ulang kapan saja. Pemindaian API memerlukan akun Pro: tanpa token yang sah API menjawab 401, dan tanpa peran Pro menjawab 403.
Pemindaian API adalah fitur Pro
Akun ini belum Pro; setelah ditingkatkan, tokennya muncul di sini. Tanpa token, atau tanpa perannya, API menjawab 401 / 403.
Coba
Atur parameternya, lihat badan permintaan ikut berubah, lalu jalankan tiga panggilan ke API.
Parameter pemindaian
Uji coba memanggil API dengan token Anda dan memerlukan akun Pro; parameter dan badan permintaannya bebas dibaca.
{
"config": {
"rotate": 1,
"rotate_var": 0.5,
"colorspace": "gray",
"blur": 0,
"noise": 0,
"border": false,
"brightness": 1.3,
"contrast": 1.3,
"resolution": 150,
"output_format": "image/jpeg"
}
}Info Tugas Pemindaian
contoh{
"jobID": "3f9c1e64-0000-4000-8000-00000000a71b",
"userID": "8f21c4b0-0000-4000-8000-000000004a17",
"createdAt": 1724409600,
"status": "completed",
"inputUploadedAt": 1724409601,
"completedAt": 1724409602,
"numPages": 6,
"downloadURL": "https://…/output/3f9c.pdf?X-Amz-…"
}Referensi API
| Metode | Jalur | Keterangan |
|---|---|---|
| POST | /v1/scan-jobs | Membuat tugas pemindaian. Kirim config dan, bila perlu, webhookUrl; Anda menerima objek tugas berstatus created beserta uploadURL bertanda tangan. |
| PUT | {uploadURL}Alamat S3 bertanda tangan dari langkah sebelumnya, yang tidak berada di api.lookscanned.io | Mengunggah PDF sumber dengan Content-Type: application/pdf dan Content-Length. Alamatnya sudah membawa tanda tangan sendiri, jadi jangan menambahkan header Authorization. |
| GET | /v1/scan-jobs/{jobID} | Membaca satu tugas, untuk penjajakan. Saat created berisi uploadURL, saat completed berisi downloadURL. |
| GET | /v1/scan-jobs | Menampilkan daftar tugas Anda sendiri, tersaring menurut jobID, status, atau createdAfter. |
401tidak ada token yang sah403akun bukan Pro404tugas tidak ada
Badan permintaan
| Bidang | Tipe | Bawaan | Keterangan |
|---|---|---|---|
| webhookUrl | string · — | — | Dipanggil sekali begitu tugas selesai, jadi Anda tidak perlu menjajaki statusnya. |
| config.colorspace | 'gray' | 'sRGB' · gray | gray | Ruang warna gambar keluaran; gray berarti hasil pindaian hitam putih. |
| config.resolution | number · 72 | 72 | Resolusi gambar keluaran, dalam DPI. |
| config.rotate | number · — | — | Rotasi seluruh dokumen, dalam derajat. |
| config.rotate_var | number · — | — | Rentang rotasi acak tiap halaman, dalam derajat — kesan kertas yang diletakkan miring. |
| config.blur | number · 0 | 0 | Tingkat kekaburan. |
| config.noise | number · 0 | 0 | Tingkat derau. |
| config.brightness | number · 1 | 1 | Kecerahan; 1 berarti tidak berubah. |
| config.contrast | number · 1 | 1 | Kontras; 1 berarti tidak berubah. |
| config.border | boolean · false | false | Apakah halaman diberi batas pemindaian. |
| config.output_format | 'image/png' | 'image/jpeg' · image/jpeg | image/jpeg | Format gambar saat halaman dirender. |
Semua bidang boleh dilewatkan. Nilai awal di bagian «Coba» — resolusi 150, rotasi 1, kecerahan dan kontras 1,3 — adalah kombinasi yang disarankan aplikasi web, bukan nilai bawaan API.
Bidang objek tugas yang perlu diperhatikan
- status
- created / processing / completed / failed — menentukan apakah dua alamat di bawah ini muncul.
- uploadURL
- Hanya selama berstatus created. Alamat unggah bertanda tangan yang punya masa berlaku.
- downloadURL
- Hanya setelah berstatus completed. Alamat unduh bertanda tangan yang punya masa berlaku.
- inputUploadedAt / completedAt
- Kapan unggahan sumber selesai dan kapan tugas selesai; selisihnya adalah waktu pemrosesan.
Pertanyaan yang sering diajukan
Apakah pemindaian API butuh Pro?
Butuh. Tanpa token yang sah API menjawab 401, dan akun tanpa peran Pro mendapat 403. Setelah meningkatkan ke Pro dan masuk, tokennya ada di halaman ini.
Bagaimana saya tahu sebuah tugas sudah selesai?
Ada dua cara: menjajaki GET /v1/scan-jobs/{jobID}, atau mengirim webhookUrl saat membuat tugas dan membiarkan layanan menghubungi Anda sekali.
Apakah hasilnya sama dengan memindai di halaman web?
Sama. Keduanya memakai implementasi efek pemindaian yang sama, dan ruang warna, resolusi, rotasi, kekaburan, derau, kecerahan, kontras, serta batas di config adalah opsi bernama sama di halaman web: parameter sama, keluaran sama. Yang berbeda hanya tempat pemrosesannya — lokal di halaman, jarak jauh lewat API.
Bolehkah saya menyimpan alamat unggah dan unduh untuk dipakai lagi?
Sebaiknya tidak. uploadURL dan downloadURL adalah alamat bertanda tangan yang punya masa berlaku; setelah kedaluwarsa Anda harus membaca ulang tugasnya untuk mendapatkan yang baru.
Berapa lama satu tugas diproses?
Tergantung jumlah halaman dan resolusinya. Dokumen beberapa halaman biasanya selesai dalam hitungan detik; resolusi lebih tinggi dan dokumen lebih panjang butuh waktu lebih lama. Selisih inputUploadedAt dan completedAt menunjukkan waktu sebenarnya.
Bagaimana kalau sebuah tugas gagal?
Statusnya menjadi failed. Penyebab yang lazim adalah file yang bukan PDF sah, pembatasan enkripsi, atau unggahan yang terputus. Pastikan file-nya bisa dibuka, lalu buat tugas baru.
Bisakah saya melihat tugas yang lalu?
Bisa. GET /v1/scan-jobs menampilkan tugas Anda sendiri dan dapat disaring menurut jobID, status, dan createdAfter — cukup untuk pencocokan atau mengunduh ulang.