.png&w=96&q=75)
Documentation
PDF Exporter for ConfluenceBrowse
Documentation
PDF Exporter for ConfluenceExamples
All examples assume two environment variables:
export PDFX_URL='YOUR_ENDPOINT_URL'
export PDFX_TOKEN='YOUR_TOKEN'
Export a Page Tree
A page and every page under it, as one merged PDF, into My exports:
curl -s -X POST "$PDFX_URL" \
-H "Authorization: Bearer $PDFX_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"pageId": "123456", "name": "Handbook"}'
Export One Page with a Template
curl -s -X POST "$PDFX_URL" \
-H "Authorization: Bearer $PDFX_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"pageId": "123456", "includeChildren": false, "template": "Report", "name": "Quarterly report"}'
Export a Whole Space as a ZIP
curl -s -X POST "$PDFX_URL" \
-H "Authorization: Bearer $PDFX_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"spaceId": "98765", "output": "zip", "name": "Engineering space"}'
Archive to a Page and Email the Team
Attach the PDF to an archive page and @mention two people there, so Confluence emails them a link:
curl -s -X POST "$PDFX_URL" \
-H "Authorization: Bearer $PDFX_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"pageId": "123456",
"name": "Release notes",
"attachTo": "234567",
"mention": ["557058:aaaa-bbbb", "712020:cccc-dddd"]
}'
GitHub Actions: Export on Every Release
Store the endpoint and token as repository secrets (PDFX_URL, PDFX_TOKEN). The release tag doubles as the requestId, so re-running the job doesn't export twice.
name: Export docs to PDF
on:
release:
types: [published]
jobs:
export:
runs-on: ubuntu-latest
steps:
- name: Start PDF export
run: |
code=$(curl -s -o response.json -w '%{http_code}' -X POST "${{ secrets.PDFX_URL }}" \
-H "Authorization: Bearer ${{ secrets.PDFX_TOKEN }}" \
-H 'Content-Type: application/json' \
-d '{"pageId": "123456", "name": "Docs ${{ github.event.release.tag_name }}", "attachTo": "234567", "requestId": "release-${{ github.event.release.tag_name }}"}')
cat response.json
# 202: started. 409: this release was already exported.
if [ "$code" != "202" ] && [ "$code" != "409" ]; then exit 1; fi
Node.js
const res = await fetch(process.env.PDFX_URL, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PDFX_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ pageId: '123456', output: 'zip', requestId: `nightly-${new Date().toISOString().slice(0, 10)}` }),
});
const { status, message } = await res.json();
if (res.status !== 202 && status !== 'duplicate') throw new Error(`${res.status} ${status}: ${message}`);
Python
import os, requests
res = requests.post(
os.environ["PDFX_URL"],
headers={"Authorization": f"Bearer {os.environ['PDFX_TOKEN']}"},
json={"spaceId": "98765", "output": "zip", "name": "Weekly backup"},
timeout=30,
)
body = res.json()
if res.status_code != 202:
raise RuntimeError(f"{res.status_code} {body['status']}: {body['message']}")
Tips
- Use a
requestIdfor anything that might be retried — CI re-runs, cron jobs, webhook redeliveries. A repeat returns409 duplicateand starts nothing. - Use one token per integration, named after it, so Recent calls and revoking stay clear.
- Prefer a ZIP for big spaces. Merged PDFs stop at 500 pages.
- Check Recent calls when a
202doesn't produce a file: it shows whether the export started, finished, or why it failed.
Stuck on something this page does not cover? Ask the developers.