Use /mergePdfs to combine PDFs in request order. The API appends every page of one document before moving to the next.
Endpoint
POST /mergePdfsAuthentication
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
| Field | Type | Required | Description |
|---|---|---|---|
pdfs_base64 | array | Conditional | List of base64-encoded PDF files |
pdfs_url | array | Conditional | List of URLs to fetch PDF files from |
files | file[] | Conditional | Multiple PDF file uploads (multipart only) |
filename | string | No | Output filename (default: “merged.pdf”) |
storage | object | No | Storage options for the merged PDF (see below) |
return_binary | boolean | No | Return PDF binary even when using storage (default: false) |
Provide at least one of pdfs_base64, pdfs_url (for JSON requests), or files (for multipart requests). You can combine pdfs_base64 and pdfs_url; the API processes base64 PDFs first and then URL PDFs.
Field details
pdfs_base64 (conditional, JSON only)
An array of base64-encoded PDF files. Each string in the array should be a complete PDF file encoded in base64. The encoded strings should not include the data URI prefix.
Example array structure:
{
"pdfs_base64": [
"JVBERi0xLjcK...", // First PDF (base64)
"JVBERi0xLjQK...", // Second PDF (base64)
"JVBERi0xLjUK..." // Third PDF (base64)
]
}pdfs_url (conditional, JSON only)
An array of URLs pointing to PDF files. Each URL is fetched server-side (follows redirects). URLs are validated against SSRF before fetching.
Example array structure:
{
"pdfs_url": [
"https://example.com/cover.pdf",
"https://example.com/chapter1.pdf",
"https://example.com/appendix.pdf"
]
}files (conditional, multipart only)
Multiple PDF file uploads via multipart form data. Each file should be a valid PDF document. Files are merged in the order they are received.
filename (optional)
The filename for the output merged PDF. Defaults to “merged.pdf”. The .pdf extension is automatically added if not provided.
Storage options
Control how the merged 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
Base64 PDFs in JSON
# First, encode your PDFs to base64
PDF1_BASE64=$(base64 -i document1.pdf)
PDF2_BASE64=$(base64 -i document2.pdf)
PDF3_BASE64=$(base64 -i document3.pdf)
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pdfs_base64": ["'"$PDF1_BASE64"'", "'"$PDF2_BASE64"'", "'"$PDF3_BASE64"'"],
"filename": "combined-document.pdf"
}' \
--output combined-document.pdfMerge two PDFs
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pdfs_base64": ["'"$(base64 -i cover.pdf)"'", "'"$(base64 -i content.pdf)"'"]
}' \
--output merged.pdfPDF URLs
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pdfs_url": [
"https://example.com/cover.pdf",
"https://example.com/chapter1.pdf",
"https://example.com/appendix.pdf"
],
"filename": "combined-document.pdf"
}' \
--output combined-document.pdfBase64 and URL inputs
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pdfs_base64": ["'"$(base64 -i cover.pdf)"'"],
"pdfs_url": ["https://example.com/chapter1.pdf"],
"filename": "mixed-sources.pdf"
}' \
--output mixed-sources.pdfMultipart file upload
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@document1.pdf" \
-F "files=@document2.pdf" \
-F "files=@document3.pdf" \
--output merged.pdfFile upload with a filename
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@chapter1.pdf" \
-F "files=@chapter2.pdf" \
-F "files=@chapter3.pdf" \
-F "filename=complete-book.pdf" \
--output complete-book.pdfPersistent storage
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pdfs_base64": ["'"$(base64 -i cover.pdf)"'", "'"$(base64 -i content.pdf)"'"],
"filename": "complete-document.pdf",
"storage": {
"mode": "default",
"filename": "complete-document.pdf",
"expires_in": 86400,
"retention_days": 30
}
}'Response
Success (memory mode)
When storage.mode is memory or not provided, returns the merged PDF as a binary file download.
Response headers:
| Header | Description |
|---|---|
Content-Type | application/pdf |
Content-Disposition | attachment; filename="merged.pdf" (or custom filename) |
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": "complete-document.pdf",
"file_size_bytes": 125678,
"page_count": 15,
"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 merged 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 merge PDFs",
"message": "Error description"
}Status codes:
| Code | Description |
|---|---|
| 200 | Success - PDF merged and 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 - PDF merge failed |
| 502 | Bad Gateway - Storage operation failed (S3 upload or URL generation) |
Merge behavior
Process
The API uses PyPDF to combine PDF documents:
- Each input PDF is validated and parsed
- PDFs are appended in the exact order provided
- All pages from the first PDF are added, then all pages from the second, and so on
- The merged document is returned as a single PDF file
Preservation
When merging PDFs, the following are preserved:
- Page dimensions and orientations
- Text content and formatting
- Images and graphics
- Internal links within each original document
Considerations
- Page numbering is recalculated for the merged document
- Cross-document links are not automatically updated
- Bookmarks/outlines from source PDFs may need manual handling
Examples
Combine report sections
Merge separately generated sections into a complete report:
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@cover-page.pdf" \
-F "files=@table-of-contents.pdf" \
-F "files=@executive-summary.pdf" \
-F "files=@main-content.pdf" \
-F "files=@appendices.pdf" \
-F "filename=annual-report-2024.pdf" \
--output annual-report-2024.pdfAssemble an invoice package
Combine invoice with supporting documents:
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@invoice.pdf" \
-F "files=@receipt.pdf" \
-F "files=@terms-and-conditions.pdf" \
-F "filename=invoice-package.pdf" \
--output invoice-package.pdfCombine scanned documents
Merge multiple scanned pages into a single document:
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@scan-page1.pdf" \
-F "files=@scan-page2.pdf" \
-F "files=@scan-page3.pdf" \
-F "filename=complete-scan.pdf" \
--output complete-scan.pdfMerge extracted pages
Combine with Extract Pages to build custom documents:
# Step 1: Extract specific pages from source documents
# (Creates extracted-from-doc1.pdf and extracted-from-doc2.pdf)
# Step 2: Merge the extracted pages
curl -X POST https://api.pdf-mcp.io/mergePdfs \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@extracted-from-doc1.pdf" \
-F "files=@extracted-from-doc2.pdf" \
-F "filename=custom-compilation.pdf" \
--output custom-compilation.pdfImplementation notes
Choose an input method
- Supply URLs in JSON for PDFs already hosted online; no download or encoding is needed
- Upload local files as multipart form data without encoding them
- Use base64 in JSON when PDFs are already in memory or come from another API call
- Combine
pdfs_base64andpdfs_urlto merge PDFs from several sources
File order
PDFs are merged in the exact order provided:
- For multipart: Order of
-F "files=@..."parameters - For JSON: Order of items in the
pdfs_base64array
Check the input order before sending the request because it determines the document structure.
Limit processing
- Keep the number of files reasonable (merging 100+ files may be slow)
- For very large documents, consider merging in batches
- Use file upload when possible to avoid base64 encoding overhead
Handle errors
- Validate each PDF before merging to identify problematic files
- If merge fails, try merging files one at a time to identify the corrupted file
- Ensure all input files are valid PDFs (not images or other formats)
Common patterns
# Merge two documents
-F "files=@doc1.pdf" -F "files=@doc2.pdf"
# Add cover page to existing document
-F "files=@cover.pdf" -F "files=@main.pdf"
# Append appendix to document
-F "files=@main.pdf" -F "files=@appendix.pdf"
# Combine multiple chapters
-F "files=@ch1.pdf" -F "files=@ch2.pdf" -F "files=@ch3.pdf"Related endpoints
- Extract pages: select pages before merging
- HTML to PDF: generate PDFs to merge
- Page count: count pages before merging
Credit usage
Each request costs 0.01 credits, regardless of page count.