PDFZippy API
Send a PDF, get the result back. Keys are issued personally during the pilot, so email us to get one.
Getting started
- Ask us for a key. We create it for you and send it privately. It is shown once, so save it straight away.
- Store it as a secret on your server, for example an environment variable named
PDFZIPPY_KEY. The examples below read it from there. - Call the API from your server, never from a web page or an app that users can inspect.
- Check your usage any time with the usage call at the bottom of this page.
Authentication
Send your key in the Authorization header on every request. Keep it secret and call the API from your server, never from a web page.
Authorization: Bearer pz_live_xxxxxxxxxxxxxxxxxxxxxxxxMerge PDFs
POST /api/v1/merge as multipart/form-data. files: 2 to 20 PDF files.
curl -X POST https://pdfzippy.me/api/v1/merge \
-H "Authorization: Bearer $PDFZIPPY_KEY" \
-F [email protected] -F [email protected] \
-o merged.pdfCompress a PDF
POST /api/v1/compress as multipart/form-data. file: one PDF. level (optional): low, medium (default) or high.
curl -X POST https://pdfzippy.me/api/v1/compress \
-H "Authorization: Bearer $PDFZIPPY_KEY" \
-F [email protected] -F level=medium \
-o compressed.pdfConvert a PDF to Word
POST /api/v1/pdf-to-word as multipart/form-data. file: one PDF. Works best on text-based PDFs, not scanned pages.
curl -X POST https://pdfzippy.me/api/v1/pdf-to-word \
-H "Authorization: Bearer $PDFZIPPY_KEY" \
-F [email protected] \
-o paper.docxUse it from your code
Node.js (version 18 or newer):
import { readFile, writeFile } from 'node:fs/promises'
const form = new FormData()
form.append('file', new Blob([await readFile('paper.pdf')], { type: 'application/pdf' }), 'paper.pdf')
const res = await fetch('https://pdfzippy.me/api/v1/pdf-to-word', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.PDFZIPPY_KEY}` },
body: form,
})
if (!res.ok) throw new Error((await res.json()).error.message)
await writeFile('paper.docx', Buffer.from(await res.arrayBuffer()))
console.log('documents left:', res.headers.get('x-quota-remaining'))Python:
import os, requests
res = requests.post(
"https://pdfzippy.me/api/v1/pdf-to-word",
headers={"Authorization": "Bearer " + os.environ["PDFZIPPY_KEY"]},
files={"file": open("paper.pdf", "rb")},
)
res.raise_for_status()
open("paper.docx", "wb").write(res.content)
print("documents left:", res.headers["X-Quota-Remaining"])Check your usage
GET /api/v1/usage does not count against your limit.
curl https://pdfzippy.me/api/v1/usage -H "Authorization: Bearer $PDFZIPPY_KEY"
{ "name": "Your company", "period": "2026-10", "limit": 250, "used": 12, "remaining": 238 }A machine-readable description of the API is at /api/v1/openapi.json (OpenAPI 3).
Limits
- Each request can be up to 4 MB in total.
- Every successful call counts as one document. Failed calls are not counted.
- Your monthly limit resets on the 1st (UTC). Each response shows it in
X-Quota-LimitandX-Quota-Remaining. - Up to 30 requests a minute per key.
- PDF to Word accepts up to 150 pages per file.
- Every response carries an
X-Request-Id. Quote it if you contact us about a problem.
Errors
Errors return JSON with a stable code and a readable message.
{ "error": { "code": "quota_exceeded", "message": "Your monthly limit of 100 documents is used up." } }401 unauthorized: missing, wrong or revoked key.400 invalid_requestorinvalid_pdf: the upload was not what the endpoint expects.413 payload_too_large: over 4 MB.422 processing_failed: we could not process that file.429 rate_limitedorquota_exceeded: slow down, or wait for the monthly reset.
Your files
Files are processed in memory and returned in the response. We do not save them, and we do not log their contents. Do not send files you are not allowed to share with a third-party service, such as patient records.