Convert SEC filings to PDF with Python
Render any SEC filing or exhibit to a clean PDF with one API call, ready to archive, print or send to a document pipeline.
EDGAR filings are HTML documents built for browsers, not for printing or archiving. The /v1/pdf endpoint renders any filing or exhibit to PDF in a headless browser and returns the file.
When a PDF is useful
- Archiving the exact filing you based a decision or a report on
- Feeding a document AI or OCR pipeline that expects PDF input
- Sharing a filing with someone who will read it on paper or a tablet
- Attaching filings to research notes or compliance records
Convert a 10-K
Pass the URL of the filing index page or of a specific document. With an index page URL, SecFeed renders the main document of the filing.
import os
import requests
BASE = "https://secfeedapi.com"
HEADERS = {"Authorization": f"Bearer {os.environ['SECFEED_KEY']}"}
url = "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/0000320193-25-000079-index.htm"
r = requests.get(f"{BASE}/v1/pdf", params={"url": url}, headers=HEADERS, timeout=120)
r.raise_for_status()
open("aapl-10k-2025.pdf", "wb").write(r.content)
print(r.headers["Content-Type"], len(r.content), "bytes", r.content[:8])
Output:
application/pdf 216507 bytes b'%PDF-1.4'
The response is the PDF itself (application/pdf), so write r.content straight to disk. Apple's 10-K comes back as a 216 KB file.
Convert a specific exhibit
Point url at the exhibit document instead of the index page:
url = "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/a10-kexhibit21109272025.htm"
Use /v1/files to get exhibit URLs.
Batch conversion
To build a PDF archive, loop over search results and convert each one:
res = requests.get(f"{BASE}/v1/filings", params={"query": "cik:320193 AND filedAt:[2026-01-01 TO *]", "size": 200},
headers=HEADERS, timeout=120).json()
for f in [x for x in res["filings"] if x["formType"] == "8-K"]:
pdf = requests.get(f"{BASE}/v1/pdf", params={"url": f["linkToFilingDetails"]}, headers=HEADERS, timeout=120)
open(f"{f['accessionNo']}.pdf", "wb").write(pdf.content)
Rendering takes a few seconds per document, so run batches sequentially or with a small amount of concurrency.
Next steps
- PDF Generator API
- Download the original files
- Dataset pages for 10-K and 8-K