Сканування через API
API перетворює PDF на реалістичну скан-копію за допомогою REST-запиту — для автоматизації та інтеграції із застосунками. Створіть завдання, завантажте PDF, а потім перевіряйте стан або чекайте на вебхук. Усього три кроки з будь-якого середовища чи мови, що підтримує HTTP-запити. Можна налаштувати колірний простір, роздільність, поворот, розмиття, шум, яскравість, контрастність і рамки.
Як працює виклик
Створіть завдання
POST /v1/scan-jobs
Надішліть config і, за потреби, webhookUrl. У відповідь отримаєте jobID та підписану адресу uploadURL.
Надішліть PDF
PUT {uploadURL}
Надішліть файл запитом PUT безпосередньо на підписану адресу S3 з попереднього кроку. Токен не потрібен.
Отримайте скан-копію
GET /v1/scan-jobs/{jobID}
Перевіряйте стан або дочекайтеся вебхука. Коли завдання матиме стан completed, збережіть результат за адресою downloadURL.
Де це стане в пригоді
Пакетна обробка на сервері
Договори, рахунки та звіти, створені на сервері, одразу отримують ефект сканування. Не потрібно щоразу запускати обробку вручну на сайті.
Інтеграція з наявною системою
Додайте дію «Експортувати скан-копію» до CRM, ERP або системи підтримки та підключіть її до API.
Автоматизовані процеси
CI, n8n, Zapier та інші інструменти запускають завдання за подією, а вебхук запускає наступний крок після завершення обробки.
Великі черги файлів
Завдання виконуються асинхронно: створіть їх, і кожне оброблятиметься окремо. Відстежуйте перебіг за допомогою 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. Перейдіть на 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. Перейдіть на Pro та увійдіть: токен з’явиться на цій сторінці.
Як дізнатися, що завдання завершено?
Є два способи: періодично надсилати GET /v1/scan-jobs/{jobID} або передати webhookUrl під час створення завдання, щоб сервіс повідомив вас одним зворотним викликом.
Чи буде результат таким самим, як на сайті?
Так. Обидва способи використовують ту саму реалізацію ефекту сканування. Колірний простір, роздільність, поворот, розмиття, шум, яскравість, контрастність і рамка в config відповідають налаштуванням на сайті під іншими назвами. Однакові параметри дають однаковий результат. Відрізняється лише місце обробки: локально на сторінці або віддалено через API.
Чи можна зберегти адреси для завантаження й отримання файлів та використовувати їх повторно?
Не варто. uploadURL і downloadURL — підписані адреси з обмеженим строком дії. Коли він спливе, отримайте дані завдання ще раз, щоб мати нові адреси.
Скільки триває обробка?
Це залежить від кількості сторінок і роздільності. Кілька сторінок зазвичай обробляються за секунди. Вища роздільність і довші документи потребують більше часу. Фактична тривалість — різниця між inputUploadedAt та completedAt.
Що робити, якщо завдання завершилося помилкою?
Стан зміниться на failed. Зазвичай причина — некоректний PDF, обмеження шифрування або перерване завантаження. Перевірте, чи відкривається файл, і створіть нове завдання.
Чи можна переглянути попередні завдання?
Так. GET /v1/scan-jobs повертає список ваших завдань із фільтрацією за jobID, status та createdAfter. Цього достатньо для звірки або повторного збереження результату.