SnapPDF + Notion
Attach a PDF to a Notion page; action SnapPDF from the meatball menu.
SnapPDF for Notion is a Notion Integration that exposes ops via the block menu on any file block. It's currently beta — limited to file blocks in databases you explicitly grant access to. Most customers use it for internal wikis where PDFs need light post-processing (compress, watermark) before linking out.
What you can build
- Run ops on any Notion file-block PDF.
- Database trigger: when a row's status hits "Ready to Ship", auto-merge attached PDFs into one.
- Writes the result back to the page as a new file block (doesn't replace the original).
- Cover-page generation from page properties (title, author, date).
- Limited by Notion's own 5MB file upload cap — compressed outputs only.
Setup
- 01Create a Notion Integrationnotion.so/my-integrations → New Integration → name it "SnapPDF" → internal integration. Copy the token.
- 02Share pages with the integrationOn each page/database you want to process: Share → Add connections → pick SnapPDF. Only shared pages are visible to the integration.
- 03Link from SnapPDF dashboardDashboard → Integrations → Notion → paste the token. Test connection.
- 04Action a blockIn Notion, click the meatball menu on a file block → Apps → SnapPDF → pick op.
- 05Set up database automation (optional)SnapPDF dashboard → Notion → Database Triggers. Pick the database, a property change to watch, and an op to run.
Code example
Underlying API flow: Notion webhook → SnapPDF merge → write new block.
app.post('/notion-webhook', async (req, res) => {
const { page_id, property } = req.body;
if (property.name !== 'Status' || property.value !== 'Ready') return res.status(200).end();
const page = await notion.pages.retrieve({ page_id });
const blocks = await notion.blocks.children.list({ block_id: page_id });
const pdfBlocks = blocks.results.filter(b => b.type === 'file' && b.file.file.url.endsWith('.pdf'));
const { pdf } = await snap.pdf.merge({
files: pdfBlocks.map(b => b.file.file.url),
});
const upload = await uploadToNotionFileService(pdf);
await notion.blocks.children.append({
block_id: page_id,
children: [{ type: 'file', file: { type: 'external', external: { url: upload.url } } }],
});
res.status(200).end();
});Known limits
- · Notion file URLs expire hourly — process within the window.
- · File-block creation uses an external-URL workaround; links depend on your CDN being up.
Pricing notes
Beta — available on Pro plan and above during beta period. Free on all tiers at GA.
Available from the Pro plan.
FAQ
Why is this beta?
Notion's file API is still rough — file URLs expire after an hour, and there's no official upload endpoint for integrations. We work around it with an external-URL pattern.
Can the integration see my whole Notion workspace?
Only pages where you explicitly add the connection. Notion's permission model is opt-in per page.
What's the file size limit?
Notion caps uploads at 5MB (free) or unlimited (paid with local-upload, but still usually small). Compress ops are the most common pairing.
Can I store the API key in Notion?
Do not. Notion isn't built for secrets. Use our dashboard to store the Notion token instead.
When will it leave beta?
When Notion ships a proper file upload API. ETA: late 2026.