API-skanning
API-skanning gör om en PDF till en trovärdig skannad kopia med ett REST-anrop, vilket passar automatiserade flöden och integrationer i appar. Skapa jobbet, ladda upp PDF:en och polla statusen eller vänta på webhooken: tre steg, från vilken miljö eller vilket språk som helst som kan skicka en HTTP-förfrågan. Färgrymd, upplösning, rotation, oskärpa, brus, ljusstyrka, kontrast och kantlinje går alla att ställa in.
Så går ett anrop till
Skapa jobbet
POST /v1/scan-jobs
Skicka din config och eventuellt en webhookUrl; du får tillbaka ett jobID och en försignerad uploadURL.
Ladda upp PDF:en
PUT {uploadURL}
Gör PUT av filen direkt till den försignerade S3-adressen från föregående steg — ingen token behövs.
Hämta den skannade kopian
GET /v1/scan-jobs/{jobID}
Polla statusen eller vänta på webhooken; när jobbet är completed hämtar du filen från downloadURL.
Var det passar
Massproduktion i backend
Avtal, fakturor och rapporter som skapas på servern går direkt genom skanningseffekten, utan att någon gör om samma sak för hand på webbsidan.
I ett befintligt system
Lägg till en åtgärd för att exportera en skannad kopia i ett CRM, ett affärssystem eller ett ärendesystem, och låt den anropa API:et.
Automatiseringskedjor
CI, n8n, Zapier och liknande startar ett jobb vid en händelse, och webhooken lämnar över till nästa steg när det är klart.
Stora köer av filer
Jobben är asynkrona: när de väl skapats bearbetas vart och ett för sig, och förloppet går att följa via status och createdAfter.
Språk och miljöer
API:et är vanlig HTTP och JSON, så vilket språk eller vilken automatiseringsplattform som helst som kan skicka en förfrågan kan anropa det.
Kodexempel
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 hör till ditt konto och kan genereras om när som helst. API-skanning kräver ett Pro-konto: utan en giltig token svarar API:et 401, och utan Pro-rollen svarar det 403.
API-skanning är en Pro-funktion
Det här kontot har inte Pro ännu; efter uppgraderingen finns token här. Utan token, eller utan rollen, svarar API:et 401 / 403.
Prova
Ställ in parametrarna, se hur förfrågans innehåll följer med och kör sedan de tre anropen mot API:et.
Skanningsparametrar
En provkörning anropar API:et med din token och kräver ett Pro-konto; parametrarna och förfrågans innehåll är fria att titta på.
{
"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"
}
}Skanningsjobb Information
exempel{
"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-…"
}API-referens
| Metod | Sökväg | Beskrivning |
|---|---|---|
| POST | /v1/scan-jobs | Skapar ett skanningsjobb. Skicka config och eventuellt webhookUrl; du får tillbaka jobbobjektet med statusen created och en försignerad uploadURL. |
| PUT | {uploadURL}Den försignerade S3-adressen från föregående steg, som inte ligger på api.lookscanned.io | Laddar upp käll-PDF:en med Content-Type: application/pdf och Content-Length. Adressen bär sin egen signatur, så lägg inte till någon Authorization-header. |
| GET | /v1/scan-jobs/{jobID} | Läser ett enskilt jobb, för pollning. Vid created innehåller det uploadURL, vid completed downloadURL. |
| GET | /v1/scan-jobs | Listar dina egna jobb, filtrerade på jobID, status eller createdAfter. |
401ingen giltig token403kontot är inte Pro404jobbet finns inte
Förfrågans innehåll
| Fält | Typ | Standard | Beskrivning |
|---|---|---|---|
| webhookUrl | string · — | — | Anropas en gång när jobbet är klart, så du slipper polla efter det. |
| config.colorspace | 'gray' | 'sRGB' · gray | gray | Färgrymd för bilden som skapas; gray ger en svartvit skannad kopia. |
| config.resolution | number · 72 | 72 | Upplösning på bilden som skapas, i dpi. |
| config.rotate | number · — | — | Rotation av hela dokumentet, i grader. |
| config.rotate_var | number · — | — | Spannet för den slumpmässiga rotationen per sida, i grader — intrycket av ett papper som lagts snett. |
| config.blur | number · 0 | 0 | Mängden oskärpa. |
| config.noise | number · 0 | 0 | Mängden brus. |
| config.brightness | number · 1 | 1 | Ljusstyrka; 1 lämnar den oförändrad. |
| config.contrast | number · 1 | 1 | Kontrast; 1 lämnar den oförändrad. |
| config.border | boolean · false | false | Om sidan ska få en kantlinje från skanningen. |
| config.output_format | 'image/png' | 'image/jpeg' · image/jpeg | image/jpeg | Bildformatet som sidorna renderas till. |
Alla fält får utelämnas. Startvärdena i ”Prova” — upplösning 150, rotation 1, ljusstyrka och kontrast 1,3 — är den kombination webbappen rekommenderar, inte API:ets standardvärden.
Fält i jobbobjektet att hålla ögonen på
- status
- created / processing / completed / failed — avgör om de två adresserna nedan finns med.
- uploadURL
- Bara medan jobbet är created. En försignerad uppladdningsadress som går ut.
- downloadURL
- Först när jobbet är completed. En försignerad nedladdningsadress som går ut.
- inputUploadedAt / completedAt
- När uppladdningen av källan blev klar och när jobbet blev klart; skillnaden är bearbetningstiden.
Vanliga frågor
Kräver API-skanning Pro?
Ja. Utan en giltig token svarar API:et 401, och ett konto utan Pro-rollen får 403. När du uppgraderat och loggat in finns token på den här sidan.
Hur vet jag när ett jobb är klart?
På två sätt: polla GET /v1/scan-jobs/{jobID}, eller skicka med en webhookUrl när du skapar jobbet och låt tjänsten höra av sig en gång.
Blir resultatet detsamma som när man skannar på webbsidan?
Ja. Båda använder samma implementation av skanningseffekten, och färgrymd, upplösning, rotation, oskärpa, brus, ljusstyrka, kontrast och kantlinje i config motsvarar webbsidans likalydande inställningar: samma parametrar ger samma resultat. Det enda som skiljer är var arbetet sker — lokalt på sidan, på distans via API:et.
Kan jag spara uppladdnings- och nedladdningsadresserna och återanvända dem?
Helst inte. uploadURL och downloadURL är försignerade adresser med begränsad livslängd; när de gått ut måste du läsa jobbet igen för att få nya.
Hur lång tid tar ett jobb?
Det beror på antalet sidor och upplösningen. Några få sidor brukar vara klara inom sekunder, medan högre upplösning och längre dokument tar längre tid. Skillnaden mellan inputUploadedAt och completedAt ger den faktiska tiden.
Vad gör jag om ett jobb misslyckas?
Statusen blir failed. De vanliga orsakerna är en fil som inte är en giltig PDF, kryptering som spärrar filen eller en avbruten uppladdning. Kontrollera att filen går att öppna och skapa ett nytt jobb.
Kan jag se tidigare jobb?
Ja. GET /v1/scan-jobs listar dina egna jobb och går att filtrera på jobID, status och createdAfter, vilket räcker för avstämning eller en ny nedladdning.