Organise
Merge PDF
Combine two or more PDFs into a single document. Each source contributes a top-level bookmark named from its original filename, so the merged outline stays navigable.
Free to try — no key required 10 credits / callSynchronous
Overview
Upload the files in the order you want them combined; receive a public R2 URL for the merged PDF. On the free-try path — callable with no key.
POST
https://api.bytefuse.in/api/v1/pdf/merge/mergeThe path segment is doubled
The router is mounted at/pdf/merge and the route is /merge, so the real path is /api/v1/pdf/merge/merge — not /api/v1/pdf/merge. Easy to get wrong.Request
Content type multipart/form-data:
filesfile[]requiredThe PDFs to merge, sent as repeated
files parts. At least two are required; each filename must end in .pdf. Order is preserved.optionsstring (JSON)optionalReserved for merge options, but currently ignored — the merge runs with a fixed config (bookmarks, metadata and forms preserved, output compressed). Malformed JSON returns
400.Default: {}async_processingbooleanoptionalAccepted but ignored — the merge always runs synchronously.Default:
falseNo enforced size or count caps
Only the “at least two PDFs” rule is enforced on this endpoint. Per-tier file/size limits are not applied here, so don’t rely on them.Response
200 OK, application/json:
200 OK
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"output_url": "https://<r2-host>/merged/20260704/<uuid>.pdf",
"pages": 42,
"size": 1048576,
"compression_ratio": null,
"processing_time": 0.85,
"message": "Merged successfully"
}job_idstringoptionalA fresh UUID. Not queryable — the sync path stores no job, so the
/{job_id}/status endpoint won’t resolve it. Download from output_url.statusstringoptionalAlways
"completed".output_urlstringoptionalPublic R2 URL of the merged PDF. No
expires_at is returned; the link is permanent under the default config.pagesint | nulloptionalTotal pages in the merged document.
sizeint | nulloptionalOutput size in bytes.
compression_rationulloptionalPresent in the schema but not set by this endpoint.
processing_timefloat | nulloptionalSeconds spent merging.
messagestringoptional"Merged successfully".The response header X-Credits-Charged reports the credits billed — 10 authenticated, 0 anonymous.
Examples
curl -X POST https://api.bytefuse.in/api/v1/pdf/merge/merge \
-H "X-API-Key: dt_live_your_key" \
-F "files=@chapter1.pdf" \
-F "files=@chapter2.pdf" \
-F "files=@chapter3.pdf"
# Omit the X-API-Key header to use the anonymous free-try path.Errors
400Fewer than two files, a non-
.pdf file, or malformed options JSON.402 / 429 / 503Insufficient credits, rate limited, or capacity/config error.
500The merge engine failed unexpectedly.
See Split PDF for the inverse operation.
