Skenování přes API
Pomocí volání REST API vytvoříte z PDF kopii se vzhledem skenu. Hodí se pro automatizované zpracování i propojení s vlastní aplikací. Vytvořte úlohu, nahrajte PDF a pak se dotazujte na stav nebo počkejte na webhook. Stačí prostředí, ze kterého lze odeslat HTTP požadavek. Nastavit můžete barevný režim, rozlišení, otočení, rozmazání, šum, jas, kontrast i okraje.
Jak volání probíhá
Vytvořte úlohu
POST /v1/scan-jobs
Odešlete konfiguraci a případně webhookUrl. Zpět dostanete jobID a předem podepsanou adresu uploadURL.
Nahrajte PDF
PUT {uploadURL}
Pošlete soubor metodou PUT přímo na podepsanou adresu S3 z předchozího kroku. Token není potřeba.
Stáhněte výsledek
GET /v1/scan-jobs/{jobID}
Dotazujte se na stav nebo počkejte na webhook. Jakmile je úloha dokončena, stáhněte soubor z downloadURL.
K čemu se API hodí
Hromadné zpracování na serveru
Smlouvy, faktury a zprávy vytvořené na serveru rovnou získají vzhled skenu. Nikdo je nemusí po jednom zpracovávat na webu.
Propojení s vaším systémem
Přidejte do CRM, ERP nebo systému pro správu požadavků akci „Exportovat jako sken“, která zavolá API.
Automatizované postupy
CI, n8n, Zapier a podobné nástroje spustí úlohu při určité události. Webhook po jejím dokončení naváže dalším krokem.
Velké fronty souborů
Úlohy se zpracovávají asynchronně. Po vytvoření běží každá samostatně a průběh můžete sledovat pomocí status a createdAfter.
Jazyky a prostředí
API používá běžné HTTP a JSON. Lze jej volat z jakéhokoli jazyka nebo automatizační platformy, která umí odeslat požadavek.
Ukázky kódu
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 patří k vašemu účtu a můžete jej kdykoli vygenerovat znovu. Skenování přes API vyžaduje účet Pro: bez platného tokenu API vrací 401, bez oprávnění Pro vrací 403.
Skenování přes API je součástí Pro
Tento účet zatím nemá Pro. Po přechodu na Pro se zde zobrazí token. Bez tokenu API vrací 401, bez oprávnění Pro vrací 403.
Vyzkoušet API
Nastavte parametry a sledujte, jak se mění tělo požadavku. Pak spusťte tři volání API.
Parametry skenování
Zkušební volání používá váš token a vyžaduje účet Pro. Parametry a tělo požadavku si můžete prohlédnout i bez něj.
{
"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"
}
}Informace o úloze
ukázka{
"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-…"
}Přehled API
| Metoda | Cesta | Popis |
|---|---|---|
| POST | /v1/scan-jobs | Vytvoří úlohu skenování. Odešlete config a případně webhookUrl. Zpět dostanete objekt úlohy se stavem created a předem podepsanou adresou uploadURL. |
| PUT | {uploadURL}Podepsaná adresa S3 z předchozího kroku, nikoli adresa na api.lookscanned.io | Nahraje zdrojové PDF s hlavičkami Content-Type: application/pdf a Content-Length. Adresa obsahuje vlastní podpis, proto nepřidávejte hlavičku Authorization. |
| GET | /v1/scan-jobs/{jobID} | Vrátí jednu úlohu pro kontrolu jejího stavu. Ve stavu created obsahuje uploadURL, po dokončení ve stavu completed obsahuje downloadURL. |
| GET | /v1/scan-jobs | Vrátí vaše úlohy filtrované podle jobID, status nebo createdAfter. |
401chybí platný token403účet nemá Pro404úloha neexistuje
Tělo požadavku
| Pole | Typ | Výchozí hodnota | Popis |
|---|---|---|---|
| webhookUrl | string · — | — | Po dokončení úlohy se zavolá jednou, takže se nemusíte dotazovat na stav. |
| config.colorspace | 'gray' | 'sRGB' · gray | gray | Barevný prostor výstupního obrázku; gray znamená sken v odstínech šedi. |
| config.resolution | number · 72 | 72 | Rozlišení výstupního obrázku v DPI. |
| config.rotate | number · — | — | Otočení celého dokumentu ve stupních. |
| config.rotate_var | number · — | — | Rozsah náhodného natočení jednotlivých stránek ve stupních. Napodobuje křivě položený papír. |
| config.blur | number · 0 | 0 | Míra rozmazání. |
| config.noise | number · 0 | 0 | Míra šumu. |
| config.brightness | number · 1 | 1 | Jas; hodnota 1 jej nemění. |
| config.contrast | number · 1 | 1 | Kontrast; hodnota 1 jej nemění. |
| config.border | boolean · false | false | Určuje, zda se ke stránce přidá okraj skenu. |
| config.output_format | 'image/png' | 'image/jpeg' · image/jpeg | image/jpeg | Formát obrázků, do kterých se stránky vykreslí. |
Všechna pole jsou volitelná. Výchozí nastavení v části „Vyzkoušet API“ — rozlišení 150, otočení 1, jas a kontrast 1,3 — odpovídají doporučení webové aplikace, nikoli výchozím hodnotám API.
Důležitá pole objektu úlohy
- status
- created / processing / completed / failed — podle stavu jsou dostupné následující dvě adresy.
- uploadURL
- Pouze ve stavu created. Podepsaná adresa pro nahrání souboru s omezenou platností.
- downloadURL
- Pouze ve stavu completed. Podepsaná adresa pro stažení souboru s omezenou platností.
- inputUploadedAt / completedAt
- Čas dokončení nahrávání a čas dokončení úlohy. Jejich rozdíl udává dobu zpracování.
Časté dotazy
Potřebuji pro skenování přes API Pro?
Ano. Bez platného tokenu API vrací 401, účtu bez oprávnění Pro vrací 403. Po přechodu na Pro se přihlaste a token najdete na této stránce.
Jak poznám, že je úloha hotová?
Můžete opakovaně volat GET /v1/scan-jobs/{jobID}, nebo při vytváření úlohy zadat webhookUrl. Služba tuto adresu po dokončení jednou zavolá.
Je výsledek stejný jako při skenování na webu?
Ano. Obě varianty používají stejné zpracování efektů. Barevný prostor, rozlišení, otočení, rozmazání, šum, jas, kontrast a okraj v config odpovídají nastavením na webu, jen mají jiné názvy. Stejné parametry dávají stejný výsledek. Liší se pouze místo zpracování: na webu probíhá místně, přes API vzdáleně.
Mohu si adresy pro nahrání a stažení uložit a používat je znovu?
Raději ne. Podepsané adresy uploadURL a downloadURL mají omezenou platnost. Po jejím vypršení znovu načtěte úlohu a získáte nové adresy.
Jak dlouho zpracování trvá?
Záleží na počtu stránek a rozlišení. Několik stránek bývá hotových za pár sekund, delší dokumenty a vyšší rozlišení trvají déle. Skutečnou dobu zpracování zjistíte z rozdílu inputUploadedAt a completedAt.
Co když úloha selže?
Stav se změní na failed. Obvyklou příčinou je neplatný soubor PDF, omezení kvůli šifrování nebo přerušené nahrávání. Ověřte, že soubor lze otevřít, a vytvořte novou úlohu.
Mohu dohledat předchozí úlohy?
Ano. GET /v1/scan-jobs vrací vaše úlohy a umožňuje filtrovat podle jobID, status a createdAfter. Můžete tak zkontrolovat zpracování nebo znovu stáhnout výsledek.