# Image to PDF

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 /imageToPdf
```

## Authentication

Send a valid API key or OAuth token in the `Authorization` header:

```
Authorization: Bearer YOUR_API_KEY
```

See [Authentication](https://pdf-mcp.io/docs/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](https://pdf-mcp.io/docs/storage-modes)).

---

## Request examples

### One image as JSON

```bash
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.pdf
```

### Multiple images as JSON

```bash
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.pdf
```

### One file upload

```bash
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.pdf
```

### Multiple file uploads

```bash
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.pdf
```

### Persistent storage

```bash
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:

```json
{
  "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

```json
{
  "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_base64` array
- **Multipart**: Order of `files` fields 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:

```bash
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.pdf
```

### Scanned document

Convert scanned document images to a single PDF:

```bash
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.pdf
```

### Screenshot archive

Archive multiple screenshots as a PDF:

```bash
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.pdf
```

---

## Python example

```python
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

```python
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

```javascript
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

```javascript
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:**
```python
import base64

with open("image.png", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode("utf-8")
```

**Node.js:**
```javascript
const fs = require('fs');
const imageBase64 = fs.readFileSync('image.png').toString('base64');
```

**Bash:**
```bash
base64 -i image.png
```

### File 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](https://pdf-mcp.io/docs/api-html-to-pdf): convert styled HTML
- [Text to PDF](https://pdf-mcp.io/docs/api-text-to-pdf): convert plain text to PDF
- [PDF to Image](https://pdf-mcp.io/docs/api-pdf-to-image): convert PDF pages to images
- [Merge PDFs](https://pdf-mcp.io/docs/api-merge-pdfs): combine multiple PDFs

## Credit usage

Each request costs **0.01 credits**, regardless of page count.
