Use /imageToPdf to put one or more images into a PDF, with one image per page. It accepts PNG, JPEG, GIF, BMP, and TIFF files.
Endpoint
POST /imageToPdfAuthentication
Send a valid API key or OAuth token in the Authorization header:
Authorization: Bearer YOUR_API_KEYSee Authentication for details.
Request body
Content-Type: application/json or multipart/form-data
JSON input
| Field | Type | Required | Description |
|---|---|---|---|
images_base64 | string[] | Yes | Array of base64-encoded image data |
filename | string | No | Output filename (default: document.pdf) |
storage | object | No | Storage options for the generated PDF (see below) |
return_binary | boolean | No | Return PDF binary even when using storage (default: false) |
Multipart form data
| Field | Type | Required | Description |
|---|---|---|---|
files | file[] | Yes | Image file uploads (multiple allowed) |
filename | string | No | Output filename (default: document.pdf) |
storage | string | No | JSON string with storage options (see below) |
Field details
images_base64 (required for JSON)
An array of base64-encoded image strings. Each image becomes a separate page in the PDF. Images are processed in order, so the first image in the array becomes page 1, and so on.
Supported image formats:
- PNG (including transparent images)
- JPEG / JPG
- GIF (first frame only for animated GIFs)
- BMP
- TIFF
files (required for multipart)
Multiple image file uploads. Each file is processed as a separate page in the resulting PDF.
filename (optional)
The filename for the downloaded PDF. If not provided, defaults to document.pdf. The .pdf extension is automatically appended if not present.
Storage options
Control how the generated PDF is stored and returned.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storage.mode | string | No | memory | Storage mode: memory, default, or byob |
storage.filename | string | No | endpoint default | Custom filename (auto-suffixed with timestamp if duplicate) |
storage.expires_in | integer | No | 3600 | Signed URL expiry in seconds (60-604800) |
storage.retention_days | integer | No | 14 | Auto-delete document after N days (1-365) |
Storage modes:
- memory: Return PDF bytes directly in response (no persistence). This is the default for REST API calls.
- default: Store in pdf-mcp S3 bucket, return JSON with document metadata and signed URL.
- byob: Store in your own S3 bucket (requires BYOB configuration).
Request examples
One image as JSON
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"images_base64": ["iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="],
"filename": "single-image.pdf"
}' \
--output single-image.pdfMultiple images as JSON
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"images_base64": [
"BASE64_ENCODED_IMAGE_1",
"BASE64_ENCODED_IMAGE_2",
"BASE64_ENCODED_IMAGE_3"
],
"filename": "photo-album.pdf"
}' \
--output photo-album.pdfOne file upload
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@/path/to/image.png" \
-F "filename=uploaded-image.pdf" \
--output uploaded-image.pdfMultiple file uploads
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@/path/to/page1.jpg" \
-F "files=@/path/to/page2.jpg" \
-F "files=@/path/to/page3.jpg" \
-F "filename=multi-page-document.pdf" \
--output multi-page-document.pdfPersistent storage
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"images_base64": ["BASE64_ENCODED_IMAGE_1", "BASE64_ENCODED_IMAGE_2"],
"storage": {
"mode": "default",
"filename": "photo-album.pdf",
"expires_in": 86400,
"retention_days": 30
}
}'Response
Success (memory mode)
When storage.mode is memory or not provided, returns the PDF as a binary file download.
Headers:
Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"Success (with storage)
When storage.mode is default or byob, returns JSON with document metadata and a signed download URL:
{
"success": true,
"document_id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://s3.eu-central-1.amazonaws.com/...",
"filename": "photo-album.pdf",
"file_size_bytes": 2456789,
"page_count": 5,
"storage_mode": "default",
"expires_at": "2024-02-15T10:30:00Z",
"signed_url_expires_at": "2024-01-15T12:00:00Z"
}| Field | Type | Description |
|---|---|---|
success | boolean | Always true on success |
document_id | string | UUID of the stored document |
url | string | Presigned URL for downloading the PDF |
filename | string | Document filename |
file_size_bytes | integer | Size of the PDF in bytes |
page_count | integer | Number of pages in the PDF |
storage_mode | string | Storage mode used (default or byob) |
expires_at | string | Auto-deletion timestamp (ISO 8601), if retention is set |
signed_url_expires_at | string | Expiration time of the signed URL (ISO 8601) |
Error
{
"error": "Failed to convert images to PDF",
"message": "Error description"
}Status codes:
| Code | Description |
|---|---|
| 200 | Success - PDF returned or stored |
| 400 | Bad Request - Invalid input or BYOB not configured |
| 401 | Unauthorized - Missing or invalid Authorization header |
| 402 | Payment Required - Insufficient credits |
| 403 | Forbidden - Invalid API key or OAuth token |
| 500 | Internal Server Error - Image conversion failed |
| 502 | Bad Gateway - Storage operation failed (S3 upload or URL generation) |
Image processing
RGBA to RGB conversion
Before adding an RGBA image to the PDF, the API converts it to RGB because PDF does not handle transparency in the same way as PNG.
PNG with transparency -> RGB (white background assumed)To keep a specific background color, add that background to the image before conversion.
Image order
Images are added to the PDF in the order they are provided:
- JSON: Order of elements in the
images_base64array - Multipart: Order of
filesfields in the request
Page sizing
Each image is rendered at its original dimensions. The PDF page size adapts to fit each image, so pages may have different sizes if images have different dimensions.
Examples
Photo album
Create a PDF photo album from multiple images:
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@photo1.jpg" \
-F "files=@photo2.jpg" \
-F "files=@photo3.jpg" \
-F "filename=vacation-photos.pdf" \
--output vacation-photos.pdfScanned document
Convert scanned document images to a single PDF:
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@scan-page1.png" \
-F "files=@scan-page2.png" \
-F "filename=scanned-document.pdf" \
--output scanned-document.pdfScreenshot archive
Archive multiple screenshots as a PDF:
curl -X POST https://api.pdf-mcp.io/imageToPdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"images_base64": ["SCREENSHOT_1_BASE64", "SCREENSHOT_2_BASE64"],
"filename": "screenshots.pdf"
}' \
--output screenshots.pdfPython example
import requests
import base64
API_KEY = "YOUR_API_KEY"
API_URL = "https://api.pdf-mcp.io/imageToPdf"
# Read and encode image to base64
with open("image.png", "rb") as f:
image_base64 = base64.b64encode(f.read()).decode("utf-8")
response = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"images_base64": [image_base64],
"filename": "python-output.pdf"
}
)
if response.status_code == 200:
with open("output.pdf", "wb") as f:
f.write(response.content)
print("PDF saved successfully!")
else:
print(f"Error: {response.status_code}")Multipart file upload
import requests
API_KEY = "YOUR_API_KEY"
API_URL = "https://api.pdf-mcp.io/imageToPdf"
# Upload multiple images directly
with open("page1.jpg", "rb") as f1, open("page2.jpg", "rb") as f2:
response = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
files=[
("files", ("page1.jpg", f1, "image/jpeg")),
("files", ("page2.jpg", f2, "image/jpeg"))
],
data={"filename": "multi-page.pdf"}
)
if response.status_code == 200:
with open("output.pdf", "wb") as f:
f.write(response.content)
print("PDF saved successfully!")
else:
print(f"Error: {response.status_code}")Node.js example
const fs = require('fs');
const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://api.pdf-mcp.io/imageToPdf';
async function generatePdf() {
// Read and encode image to base64
const imageBase64 = fs.readFileSync('image.png').toString('base64');
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
images_base64: [imageBase64],
filename: 'nodejs-output.pdf'
})
});
if (response.ok) {
const buffer = await response.arrayBuffer();
fs.writeFileSync('output.pdf', Buffer.from(buffer));
console.log('PDF saved successfully!');
} else {
console.error('Error:', response.status);
}
}
generatePdf();File upload with FormData
const fs = require('fs');
const FormData = require('form-data');
const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://api.pdf-mcp.io/imageToPdf';
async function generatePdf() {
const form = new FormData();
form.append('files', fs.createReadStream('page1.jpg'));
form.append('files', fs.createReadStream('page2.jpg'));
form.append('filename', 'multi-page.pdf');
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
...form.getHeaders()
},
body: form
});
if (response.ok) {
const buffer = await response.arrayBuffer();
fs.writeFileSync('output.pdf', Buffer.from(buffer));
console.log('PDF saved successfully!');
} else {
console.error('Error:', response.status);
}
}
generatePdf();Implementation notes
Prepare images
- Consistent sizing: For a uniform look, resize images to the same dimensions before conversion
- Orientation: Rotate images to the correct orientation before uploading
- Compression: Pre-compress large images to reduce API payload size and processing time
Base64 encoding
When using the JSON input method, encode your images to base64:
Python:
import base64
with open("image.png", "rb") as f:
image_base64 = base64.b64encode(f.read()).decode("utf-8")Node.js:
const fs = require('fs');
const imageBase64 = fs.readFileSync('image.png').toString('base64');Bash:
base64 -i image.pngFile size limits
- Keep individual images under 10MB for faster processing
- For large batches, consider splitting into multiple requests
- Use JPEG format for photos (smaller file size)
- Use PNG for screenshots or images with text (better quality)
Related endpoints
- HTML to PDF: convert styled HTML
- Text to PDF: convert plain text to PDF
- PDF to Image: convert PDF pages to images
- Merge PDFs: combine multiple PDFs
Credit usage
Each request costs 0.01 credits, regardless of page count.