Home / Tutorials / Fetch & download
Fetch & download

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

More fetch & download tutorials

Run this tutorial with your own key

500 free API calls a month. Every example on this page works on the free plan.

Get free API key →