Upload a PDF or image (or provide a URL) and receive a PDF with a professional scanned appearance: optional tilt, noise, dirty edges, and A4 output.
POST https://doc-ready.com/api/v1/convert.php
Authentication: Required. Send your API key via Authorization: Bearer YOUR_KEY, X-API-Key: YOUR_KEY, or api_key=YOUR_KEY (query or form).
Content-Type: multipart/form-data (for file upload) or application/x-www-form-urlencoded (when using file_url only).
| Parameter | Type | Required | Description |
|---|---|---|---|
file or pdf | file | One of file or file_url | PDF, JPG, PNG, TIFF, or WebP file upload. |
file_url | string | One of file or file_url | HTTP or HTTPS URL of a PDF or image (max 50 MB, 30s timeout). |
color_mode | string | Optional | bw (grayscale, default) or color. |
rotate | number | Optional | Page tilt in degrees, from -1.5 to 1.5. Default 0. |
noise | number | Optional | Noise amount 0–1. Default 0.1. |
dirty_background | 0|1 | Optional | 1 = visible dark edges around page (default). 0 = clean. |
force_a4 | 0|1 | Optional | 1 = fit output to A4 (default). 0 = keep original size. |
api_key | string | If not in header | Your API key (alternative to Authorization / X-API-Key). |
Success (200): Response body is the generated PDF (binary). Content-Type: application/pdf, Content-Disposition: attachment with filename.
Error (4xx/5xx): JSON body with {"ok": false, "error": "message"}.
| Code | Meaning |
|---|---|
| 400 | Bad request: missing file/file_url, invalid format, or file too large. |
| 401 | Missing or invalid API key. |
| 405 | Method not allowed (use POST). |
| 500 | Conversion or server error. |
| 503 | Conversion not available (server missing Imagick/Ghostscript). |
curl -X POST "https://doc-ready.com/api/v1/convert.php?" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@/path/to/document.pdf" \
-F "color_mode=bw" \
-F "force_a4=1" \
--output scanned.pdf
curl -X POST "https://doc-ready.com/api/v1/convert.php" \
-H "X-API-Key: YOUR_API_KEY" \
-d "file_url=https://example.com/doc.pdf" \
-d "color_mode=color" \
--output scanned.pdf
<?php
$apiKey = 'YOUR_API_KEY';
$convertUrl = 'https://doc-ready.com/api/v1/convert.php';
$cfile = new CURLFile('/path/to/document.pdf', 'application/pdf', 'doc.pdf');
$post = [
'file' => $cfile,
'color_mode' => 'bw',
'force_a4' => '1',
];
$ch = curl_init($convertUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . $apiKey],
CURLOPT_RETURNTRANSFER => true,
]);
$pdf = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code === 200 && $pdf) {
file_put_contents('scanned.pdf', $pdf);
} else {
$err = json_decode($pdf, true);
echo 'Error: ' . ($err['error'] ?? 'Unknown');
}
import requests
url = "https://doc-ready.com/api/v1/convert.php"
headers = {"X-API-Key": "YOUR_API_KEY"}
files = {"file": open("/path/to/document.pdf", "rb")}
data = {"color_mode": "bw", "force_a4": "1"}
r = requests.post(url, headers=headers, files=files, data=data)
if r.status_code == 200:
with open("scanned.pdf", "wb") as f:
f.write(r.content)
else:
print(r.json().get("error", "Error"))
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');
const form = new FormData();
form.append('file', fs.createReadStream('/path/to/document.pdf'));
form.append('color_mode', 'bw');
form.append('force_a4', '1');
fetch('https://doc-ready.com/api/v1/convert.php', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
...form.getHeaders(),
},
body: form,
})
.then(res => res.ok ? res.buffer() : res.json().then(j => Promise.reject(new Error(j.error))))
.then(buf => require('fs').writeFileSync('scanned.pdf', buf))
.catch(err => console.error(err.message));
Each successful call is counted in your account. View your usage in My account. There are no hard limits; counts are for transparency and future billing.