Prerequisites
- Python 3.8+ and the
requestslibrary (pip install requests). - An API key: create a free account and copy your key from the dashboard. Store it in an environment variable rather than in code:
export PDF_SUMMARIZE_KEY="sk_live_..."
Your first PDF summary in Python
- Install requests
pip install requests. - Set your API keyIn the
PDF_SUMMARIZE_KEYenvironment variable. - Send the PDFAs multipart/form-data with the field name
file. - Read the JSONThe summary is in
summary; checksuccessand the HTTP status.
import os
import requests
API_URL = "https://pdf-summarize.com/api/summarize.php"
API_KEY = os.environ["PDF_SUMMARIZE_KEY"]
def summarize_pdf(path, length="medium", fmt="bullets", lang="auto"):
with open(path, "rb") as f:
resp = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": (os.path.basename(path), f, "application/pdf")},
data={"length": length, "format": fmt, "outputLang": lang, "includeKeywords": "1"},
timeout=180,
)
data = resp.json()
if resp.status_code != 200 or not data.get("success"):
raise RuntimeError(f"{resp.status_code}: {data.get('error', data)}")
return data
result = summarize_pdf("annual-report.pdf")
print(result["summary"])
print("Pages:", result["page_count"], "| Keywords:", result.get("keywords"))
The response
{
"success": true,
"summary": "- Revenue grew 6% to ...",
"keywords": "revenue, margin, guidance, ...",
"page_count": 48,
"original_length": 182340,
"summary_length": 1210,
"processing_time": 6.214,
"requests_remaining": 4987
}
requests_remaining is your remaining monthly quota (-1 means unlimited).
Streaming the summary
For long documents or interactive apps, stream the summary as it's generated:
import json
def stream_summary(path):
with open(path, "rb") as f:
with requests.post(
API_URL + "?stream=1",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": (os.path.basename(path), f, "application/pdf")},
data={"length": "long", "format": "mixed"},
stream=True, timeout=300,
) as resp:
resp.raise_for_status()
for line in resp.iter_lines(decode_unicode=True):
if not line or not line.startswith("data: "):
continue
payload = line[6:]
if payload == "[DONE]":
break
event = json.loads(payload)
if "error" in event:
raise RuntimeError(event["error"])
if event.get("type") == "summary":
print(event["content"], end="", flush=True)
stream_summary("research-paper.pdf")
Processing a folder of PDFs
import pathlib, time
out_dir = pathlib.Path("summaries")
out_dir.mkdir(exist_ok=True)
for pdf in sorted(pathlib.Path("pdfs").glob("*.pdf")):
target = out_dir / (pdf.stem + ".md")
if target.exists():
continue # resume-friendly
for attempt in range(3):
try:
data = summarize_pdf(str(pdf), length="long", fmt="mixed")
target.write_text(data["summary"], encoding="utf-8")
print("ok", pdf.name, data["page_count"], "pages")
break
except RuntimeError as e:
if str(e).startswith("429"):
time.sleep(30 * (attempt + 1)) # rate limit: back off
else:
print("failed", pdf.name, e)
break
Errors to handle
| Status | Meaning | What to do |
|---|---|---|
| 400 | Missing file, wrong type, page limit exceeded | Check the file and your plan's page limit |
| 401 | Missing or invalid API key | Check the Authorization header |
| 403 | Account suspended | Contact support |
| 413 | File too large | Compress or split the PDF |
| 422 | No readable text (empty, protected or unreadable scan) | Remove password; improve scan |
| 429 | Rate limit or monthly quota reached | Back off and retry, or upgrade |
| 500 | Summarization temporarily unavailable | Retry with backoff |
Tips
- Set timeouts generously (2-3 minutes) for long PDFs.
- Cache results by file hash to avoid paying twice for the same document.
- Keep keys server-side — never ship them in a front-end or mobile app.
- Full parameter reference: the API documentation.
Frequently asked questions
Is there a free API plan?
Yes. The free plan includes a monthly quota of requests with no credit card. See pricing.
Can I send a PDF URL instead of a file?
The API takes the file itself. Download the PDF in your code (e.g. with requests) and send the bytes.
Which languages can the summary be in?
Use outputLang=auto to keep the document's language, or a language code such as en, fr, es, de.
How do I summarize scanned PDFs through the API?
Send them like any PDF; the extraction pipeline falls back to OCR when there is no usable text layer.