Σάρωση μέσω API
Η σάρωση μέσω API μετατρέπει ένα PDF σε αντίγραφο που μοιάζει σαρωμένο, με μια κλήση REST. Είναι κατάλληλη για αυτοματισμούς και ενσωμάτωση σε εφαρμογές. Δημιουργήστε μια εργασία, μεταφορτώστε το PDF και ελέγξτε την κατάσταση ή περιμένετε το webhook. Τρία βήματα, από οποιοδήποτε περιβάλλον ή γλώσσα μπορεί να στείλει αίτημα HTTP. Μπορείτε να ρυθμίσετε τη χρωματική λειτουργία, την ανάλυση, την περιστροφή, το θάμπωμα, τον θόρυβο, τη φωτεινότητα, την αντίθεση και το περίγραμμα.
Πώς λειτουργεί μια κλήση
Δημιουργήστε την εργασία
POST /v1/scan-jobs
Στείλτε το config και προαιρετικά ένα webhookUrl. Θα λάβετε ένα jobID και ένα προϋπογεγραμμένο uploadURL.
Μεταφορτώστε το PDF
PUT {uploadURL}
Στείλτε το αρχείο με PUT απευθείας στην προϋπογεγραμμένη διεύθυνση S3 του προηγούμενου βήματος. Δεν χρειάζεται διακριτικό.
Λάβετε το σαρωμένο αντίγραφο
GET /v1/scan-jobs/{jobID}
Ελέγχετε την κατάσταση ή περιμένετε το webhook. Όταν η εργασία ολοκληρωθεί, κατεβάστε το αρχείο από το downloadURL.
Πού χρησιμεύει
Μαζική παραγωγή στον διακομιστή
Συμβάσεις, τιμολόγια και αναφορές που δημιουργούνται στον διακομιστή αποκτούν απευθείας το εφέ σάρωσης, χωρίς χειροκίνητη επανάληψη στη σελίδα.
Ενσωμάτωση σε υπάρχον σύστημα
Προσθέστε μια ενέργεια «Εξαγωγή σαρωμένου αντιγράφου» σε CRM, ERP ή σύστημα διαχείρισης αιτημάτων, η οποία καλεί το API.
Ροές αυτοματισμού
CI, n8n, Zapier και παρόμοια εργαλεία ξεκινούν μια εργασία όταν συμβεί ένα γεγονός. Το webhook ενεργοποιεί το επόμενο βήμα όταν η εργασία ολοκληρωθεί.
Μεγάλες ουρές αρχείων
Οι εργασίες είναι ασύγχρονες: δημιουργήστε τις και καθεμία επεξεργάζεται ανεξάρτητα. Παρακολουθήστε την πρόοδο μέσω των status και createdAfter.
Γλώσσες και περιβάλλοντα
Το API χρησιμοποιεί HTTP και JSON. Μπορεί να κληθεί από οποιαδήποτε γλώσσα ή πλατφόρμα αυτοματισμού που στέλνει αιτήματα.
Παραδείγματα κώδικα
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
Το διακριτικό ανήκει στον λογαριασμό σας και μπορείτε να το αναδημιουργήσετε ανά πάσα στιγμή. Η σάρωση μέσω API απαιτεί Pro: χωρίς έγκυρο διακριτικό το API απαντά με 401, ενώ χωρίς τον ρόλο Pro απαντά με 403.
Η σάρωση μέσω API είναι λειτουργία Pro
Αυτός ο λογαριασμός δεν έχει ακόμη Pro. Αναβαθμίστε και το διακριτικό θα εμφανιστεί εδώ. Χωρίς διακριτικό ή χωρίς τον απαιτούμενο ρόλο, το API απαντά με 401 / 403.
Δοκιμάστε το
Ορίστε τις παραμέτρους, δείτε το σώμα του αιτήματος να ενημερώνεται και εκτελέστε τις τρεις κλήσεις προς το API.
Παράμετροι σάρωσης
Η δοκιμή καλεί το API με το διακριτικό σας και απαιτεί λογαριασμό Pro. Μπορείτε να δείτε τις παραμέτρους και το σώμα του αιτήματος δωρεάν.
{
"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"
}
}Στοιχεία εργασίας σάρωσης
παράδειγμα{
"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
| Μέθοδος | Διαδρομή | Περιγραφή |
|---|---|---|
| POST | /v1/scan-jobs | Δημιουργήστε μια εργασία σάρωσης. Στείλτε config και προαιρετικά webhookUrl. Επιστρέφεται το αντικείμενο εργασίας με κατάσταση created και προϋπογεγραμμένο uploadURL. |
| PUT | {uploadURL}Η προϋπογεγραμμένη διεύθυνση S3 του προηγούμενου βήματος, όχι διεύθυνση στο api.lookscanned.io | Μεταφορτώστε το αρχικό PDF με Content-Type: application/pdf και Content-Length. Η διεύθυνση περιέχει τη δική της υπογραφή, οπότε μην προσθέτετε κεφαλίδα Authorization. |
| GET | /v1/scan-jobs/{jobID} | Ανακτήστε μία εργασία για να ελέγξετε την κατάστασή της. Όσο η κατάσταση είναι created, περιλαμβάνει uploadURL. Όταν γίνει completed, περιλαμβάνει downloadURL. |
| GET | /v1/scan-jobs | Δείτε τις δικές σας εργασίες με φίλτρα jobID, status ή createdAfter. |
401δεν υπάρχει έγκυρο διακριτικό403ο λογαριασμός δεν έχει Pro404δεν υπάρχει τέτοια εργασία
Σώμα αιτήματος
| Πεδίο | Τύπος | Προεπιλογή | Περιγραφή |
|---|---|---|---|
| webhookUrl | string · — | — | Καλείται μία φορά όταν ολοκληρωθεί η εργασία, ώστε να μη χρειάζονται επαναλαμβανόμενοι έλεγχοι κατάστασης. |
| config.colorspace | 'gray' | 'sRGB' · gray | gray | Χρωματικός χώρος της τελικής εικόνας. Η τιμή gray παράγει σάρωση σε κλίμακα του γκρι. |
| config.resolution | number · 72 | 72 | Ανάλυση της τελικής εικόνας σε DPI. |
| config.rotate | number · — | — | Περιστροφή ολόκληρου του εγγράφου σε μοίρες. |
| config.rotate_var | number · — | — | Εύρος τυχαίας περιστροφής ανά σελίδα, σε μοίρες, για να μοιάζει με χαρτί που τοποθετήθηκε λοξά. |
| config.blur | number · 0 | 0 | Ένταση θαμπώματος. |
| config.noise | number · 0 | 0 | Ένταση θορύβου. |
| config.brightness | number · 1 | 1 | Φωτεινότητα· η τιμή 1 τη διατηρεί αμετάβλητη. |
| config.contrast | number · 1 | 1 | Αντίθεση· η τιμή 1 τη διατηρεί αμετάβλητη. |
| config.border | boolean · false | false | Προσθήκη περιγράμματος σάρωσης στη σελίδα. |
| config.output_format | 'image/png' | 'image/jpeg' · image/jpeg | image/jpeg | Μορφή εικόνας στην οποία αποδίδονται οι σελίδες. |
Όλα τα πεδία είναι προαιρετικά. Οι αρχικές τιμές της ενότητας «Δοκιμάστε το» — ανάλυση 150, περιστροφή 1, φωτεινότητα και αντίθεση 1.3 — είναι ο συνδυασμός που προτείνει η εφαρμογή ιστού, όχι οι προεπιλογές του API.
Χρήσιμα πεδία του αντικειμένου εργασίας
- status
- created / processing / completed / failed — καθορίζει αν υπάρχουν οι δύο παρακάτω διευθύνσεις.
- uploadURL
- Μόνο στην κατάσταση created. Προϋπογεγραμμένη διεύθυνση μεταφόρτωσης με ημερομηνία λήξης.
- downloadURL
- Μόνο στην κατάσταση completed. Προϋπογεγραμμένη διεύθυνση λήψης με ημερομηνία λήξης.
- inputUploadedAt / completedAt
- Πότε ολοκληρώθηκε η μεταφόρτωση του αρχείου και πότε ολοκληρώθηκε η εργασία. Η διαφορά τους είναι ο χρόνος επεξεργασίας.
Συχνές ερωτήσεις
Χρειάζεται Pro για σάρωση μέσω API;
Ναι. Χωρίς έγκυρο διακριτικό το API απαντά με 401, ενώ λογαριασμός χωρίς ρόλο Pro λαμβάνει 403. Αναβαθμίστε και συνδεθείτε για να δείτε το διακριτικό σε αυτή τη σελίδα.
Πώς ξέρω ότι ολοκληρώθηκε μια εργασία;
Με δύο τρόπους: ελέγχετε περιοδικά το GET /v1/scan-jobs/{jobID} ή δώστε webhookUrl κατά τη δημιουργία της εργασίας, ώστε η υπηρεσία να σας ειδοποιήσει μία φορά.
Είναι το αποτέλεσμα ίδιο με τη σάρωση στη σελίδα;
Ναι. Και οι δύο τρόποι χρησιμοποιούν την ίδια υλοποίηση εφέ σάρωσης. Η χρωματική λειτουργία, η ανάλυση, η περιστροφή, το θάμπωμα, ο θόρυβος, η φωτεινότητα, η αντίθεση και το περίγραμμα στο config αντιστοιχούν στις επιλογές της σελίδας με άλλα ονόματα. Οι ίδιες παράμετροι δίνουν το ίδιο αποτέλεσμα. Διαφέρει μόνο ο τόπος επεξεργασίας: τοπικά στη σελίδα, απομακρυσμένα μέσω API.
Μπορώ να αποθηκεύσω τις διευθύνσεις μεταφόρτωσης και λήψης για να τις ξαναχρησιμοποιήσω;
Καλύτερα όχι. Τα uploadURL και downloadURL είναι προϋπογεγραμμένες διευθύνσεις με περιορισμένη διάρκεια ισχύος. Όταν λήξουν, ανακτήστε ξανά την εργασία για να λάβετε νέες.
Πόσο διαρκεί μια εργασία;
Εξαρτάται από τον αριθμό σελίδων και την ανάλυση. Λίγες σελίδες συνήθως ολοκληρώνονται σε δευτερόλεπτα. Υψηλότερη ανάλυση ή μεγαλύτερα έγγραφα χρειάζονται περισσότερο χρόνο. Η διαφορά μεταξύ inputUploadedAt και completedAt είναι ο πραγματικός χρόνος επεξεργασίας.
Τι γίνεται αν αποτύχει μια εργασία;
Η κατάσταση γίνεται failed. Συνήθεις αιτίες είναι μη έγκυρο PDF, περιορισμοί κρυπτογράφησης ή διακοπή της μεταφόρτωσης. Ελέγξτε ότι το αρχείο ανοίγει και δημιουργήστε νέα εργασία.
Μπορώ να δω παλαιότερες εργασίες;
Ναι. Το GET /v1/scan-jobs εμφανίζει τις δικές σας εργασίες και δέχεται φίλτρα jobID, status και createdAfter για έλεγχο του ιστορικού ή επανάληψη λήψης.