Post a list of public PDF links. We fetch them, concatenate them in the order you gave, and hand back a public URL to the merged file β valid for one hour.
Free β weekly limit, or $20/mo unlocked βDownloads every PDF you list, merges them in order, returns a public link to the result.
Serves the merged PDF. No API key needed β the token is the secret. Re-fetchable as often as you like until it expires (1 hour). Append ?dl=1 to force a download instead of the browser viewer.
| Header | Value |
|---|---|
Content-Type | application/json |
X-API-Key | Your API key |
| Field | Type | Description |
|---|---|---|
urls |
string[] | Public http(s) links to the PDFs, in the order they should appear. 2 to 50 entries, 100 MB per file, 300 MB total. |
filename |
string | Name of the merged file. Default: merged.pdf (optional) |
curl -X POST https://trilogicppp.com/api/pdf-merge \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key" \
-d '{
"urls": [
"https://example.com/invoice-a.pdf",
"https://example.com/invoice-b.pdf"
],
"filename": "invoices-q3.pdf"
}'
{
"url": "https://trilogicppp.com/api/pdf-merge/download/550e8400-e29b-...",
"expires_at": "2026-09-17T14:30:00.000Z",
"token": "550e8400-e29b-41d4-a716-446655440000",
"filename": "invoices-q3.pdf",
"sources": 2,
"pages": 14,
"bytes": 248113
}
| Status | Meaning |
|---|---|
400 | Fewer than 2 URLs, more than 50, or a malformed link |
401 | Missing or invalid API key |
403 | A URL resolves to a private / internal address |
404 | Download token not found or expired |
413 | A source exceeds 100 MB, or the job exceeds 300 MB |
415 | A URL returned something that isn't a PDF |
429 | Weekly limit reached |
502 | A source was unreachable or returned an error status |
504 | A source took too long to download (30 s per file) |
Every error carries a stable code alongside the human message β e.g. not_a_pdf, blocked_host, source_too_large.
const res = await fetch('https://trilogicppp.com/api/pdf-merge', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-key',
},
body: JSON.stringify({
urls: ['https://example.com/a.pdf', 'https://example.com/b.pdf'],
}),
});
const { url, pages } = await res.json();
console.log(url, pages); // public link + page count
import requests
r = requests.post(
'https://trilogicppp.com/api/pdf-merge',
headers={'X-API-Key': 'your-key'},
json={'urls': ['https://example.com/a.pdf', 'https://example.com/b.pdf'],
'filename': 'report.pdf'},
)
print(r.json()['url']) # public link, valid 1 hour
$ch = curl_init('https://trilogicppp.com/api/pdf-merge');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-API-Key: your-key'],
CURLOPT_POSTFIELDS => json_encode(['urls' => [
'https://example.com/a.pdf',
'https://example.com/b.pdf',
]]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data['url'];