Free PDF tool
Merge PDF files
Add two or more PDFs, put them in order and download a single combined document. Pages keep their size and orientation.
Your PDF stays on your device
- Free, no account needed
- Built on the open-source libraries pdf-lib and PDF.js
How it works
Merge PDF files in 4 steps
- 1
Add your PDFs
Drop the files onto the tool or choose them from your device. You can add more at any time.
- 2
Set the order
Move files up or down until they are in the order the pages should appear.
- 3
Merge
Select Merge PDFs. The combined file is created in your browser within a few seconds.
- 4
Download
Save the merged PDF. Nothing is uploaded, so you can close the page afterwards.
Questions
Frequently asked questions
Are my files uploaded to a server?
No. The tool runs entirely in your browser: the PDF is read, changed and saved on your device, and its contents are never sent to our servers.
Does merging change the quality of my pages?
No. Pages are copied as they are, including text, vector graphics and images, so there is no re-compression and no loss of quality.
Are bookmarks and form fields kept?
Page content is kept in full. The bookmark outline of the source files is not carried over, and interactive form fields may no longer be editable in the merged file.
Can I use password-protected PDFs?
Not in the browser tool. Encrypted PDFs cannot be modified without the password, so the tool reports them instead of producing a broken file. Remove the protection with the software that created it, then try again.
Is there a file size or page limit?
There is no fixed limit because processing happens on your device. Very large files (several hundred megabytes) depend on your browser's available memory; if a file fails to open, try closing other tabs or use the API for server-side processing.
Automate it
Do the same in your application with Dynamic Document API
Merge up to 200 sources in one request: rendered documents, uploads or URLs. Useful for attaching terms and conditions to every generated invoice.
POST /v1/pdf-tools/mergeAvailablecurl -X POST https://api-eu.dynamicdocumentapi.com/v1/pdf-tools/merge \
-H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"sources": [
{
"render_id": "rnd_01J9ZM1X3F7R8K2C4V6B8N0P2Q",
"file_id": "file_01J9ZM4T6Y8U0I2O4P6A8S0D2F"
},
{
"url": "https://example.com/terms-2026.pdf"
}
],
"bookmarks": "filenames",
"filename": "invoice-with-terms.pdf"
}'const response = await fetch("https://api-eu.dynamicdocumentapi.com/v1/pdf-tools/merge", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
"sources": [
{
"render_id": "rnd_01J9ZM1X3F7R8K2C4V6B8N0P2Q",
"file_id": "file_01J9ZM4T6Y8U0I2O4P6A8S0D2F"
},
{
"url": "https://example.com/terms-2026.pdf"
}
],
"bookmarks": "filenames",
"filename": "invoice-with-terms.pdf"
}),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const result = await response.json();
console.log(result);import os
import uuid
import requests
response = requests.post(
"https://api-eu.dynamicdocumentapi.com/v1/pdf-tools/merge",
headers={
"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"sources": [
{
"render_id": "rnd_01J9ZM1X3F7R8K2C4V6B8N0P2Q",
"file_id": "file_01J9ZM4T6Y8U0I2O4P6A8S0D2F",
},
{
"url": "https://example.com/terms-2026.pdf",
},
],
"bookmarks": "filenames",
"filename": "invoice-with-terms.pdf",
},
timeout=90,
)
response.raise_for_status()
print(response.json())