Commercial workflow page

Fill PDFs With Python — JSON-to-PDF API for Python Backends

Send a JSON payload from Python with requests or httpx, get back a filled PDF. No PyPDF2 / pypdf field-coordinate math, no reportlab redrawing, no LibreOffice headless. Free tier available.

Why most Python teams stop rolling their own PDF fill code

Filling a PDF programmatically from Python sounds straightforward until production hits an unusual form. pypdf and PyPDF2 can update text fields but the API around radio groups, checkbox export values, appearance streams, and AcroForm flattening is awkward and frequently produces filled forms that look correct in some PDF viewers but blank or partially blank in others. fillpdf wraps pdftk, which is unmaintained and a heavy system dependency. reportlab generates PDFs from scratch but is not a fillable-form filler — you would be redrawing the document. The LibreOffice headless approach works but ships a 400MB binary and is painful to package on serverless.

The DullyPDF API replaces all of that with a single requests.post call. The PDF is detected and the field map is frozen at template publish time, so the JSON contract is stable across runs and across PDF readers.

Minimal Python example

A typical call from a Python backend looks like the snippet below. The endpoint URL and API key come from the API Fill modal in the DullyPDF workspace after you publish a saved template. The JSON body uses three top-level keys: a `data` object whose keys are the cleaned field names from your saved template, an `exportMode` flag (`"flat"` returns a non-editable PDF, `"editable"` keeps the AcroForm intact), and a `strict` boolean (set true so unknown payload keys are rejected instead of silently ignored).

Authentication is HTTP Basic with the API key as the username and a blank password — pass `auth=(api_key, "")` to requests, or set the Authorization header manually as `Basic base64(api_key + ":")`. The response body is the raw PDF.

  • import os, requests
  • api_key = os.environ["DULLYPDF_API_KEY"]
  • res = requests.post(
  • "https://api.dullypdf.com/api/v1/fill/<TEMPLATE_ID>.pdf",
  • auth=(api_key, ""),
  • json={"data": {"patient_name": "Jane Doe", "patient_email": "jane@example.com"}, "exportMode": "flat", "strict": True},
  • )
  • res.raise_for_status()
  • with open("filled.pdf", "wb") as fh: fh.write(res.content)
  • # For async: httpx.AsyncClient.post with the same auth tuple and json body.

Where this fits in a typical Python app

Most Python teams reaching for an external PDF fill API have a Flask, FastAPI, or Django backend with a record (a customer, an enrollment, a claim, a quote) that needs to be turned into a specific PDF — an ACORD certificate, a 1099 form, an HR onboarding packet, a state-specific government form, a generated invoice. They have already tried pypdf or fillpdf and ran into one of: forms that flatten incorrectly, radio groups that come back blank, output that looks fine in Preview but blank in Adobe Reader, or pdftk dependencies that broke on the first deploy.

In that shape, the API call is a one-line replacement. The JSON keys mirror the dictionary you would have built anyway. The output PDF is consistent across viewers because the fill engine and field detection are versioned with the saved template.

  • Insurance ops: render a filled ACORD 25 from the policy row after binding.
  • Tax / accounting: render filled 1099/W-2/W-9 PDFs from accounting database records.
  • Government / immigration: render filled USCIS or state forms from intake records.
  • Internal batch: nightly job renders N filled certificates for the day's submissions.

Comparison with native Python PDF approaches

There is a place for in-process PDF libraries. pypdf is good for low-level inspection and trivial text-only field updates. reportlab is the right tool when you are generating a PDF from scratch and not filling an existing template. LibreOffice headless works for one-off conversions but is heavy. The DullyPDF API is the right tool when the source PDF is non-trivial, the field set needs detection, or the same template is going to be filled by more than one caller across more than one Python service.

  • pypdf / PyPDF2: good for inspection, weak on radio groups + appearance streams + flattening.
  • fillpdf: wraps pdftk, which is unmaintained and a heavy system dependency.
  • reportlab: PDF generation from scratch, not fillable-form filling. Different tool category.
  • LibreOffice headless: works but ships ~400MB, painful on serverless / Lambda.
  • DullyPDF API: one requests.post, template-scoped schema, field detection done once.

Deployment shapes that work well

Because the API is a single HTTPS endpoint, every Python deployment shape works without extra setup. Long-running Flask, FastAPI, Django Channels, Celery batch workers, AWS Lambda with the slim runtime, Google Cloud Run, Heroku, Fly.io, and serverless Python runtimes all work because there is no system-level dependency to install. Cold starts stay fast because no PDF library has to load into memory on the calling side.

When you outgrow the free tier

The free tier covers prototypes and low-volume production. Once you cross the request quota, the single Premium tier raises the limits without a separate plan negotiation. The published endpoint and field schema do not change when the plan changes — only the quotas do. That means scaling up does not force a code change in your Python service.

Why teams use PDF Fill API for Python

  • requests.post a JSON body, get a filled PDF back. No PyPDF2 / pypdf field math, no reportlab redrawing.
  • Works from any Python deployment: Flask, FastAPI, Django, Lambda, Cloud Run, batch jobs.
  • Free tier covers low-volume workloads end to end before any paid commitment.

Implementation signals for PDF Fill API for Python

  • API call is a standard HTTPS POST — works with requests, httpx, urllib, aiohttp.
  • Field schema is downloadable from the saved template so the JSON contract is visible to the calling code.
  • Each published endpoint is template-scoped so a template revision does not silently break callers.

Need deeper technical details about pdf fill api for python? Use the Rename + Mapping docs and Search & Fill docs to validate exact behavior.

Frequently asked questions about PDF Fill API for Python

Do I need a Python SDK?

No. The API is plain HTTPS + JSON. requests, httpx, urllib, and aiohttp all work without any DullyPDF-specific package install.

Does this replace pypdf or PyPDF2?

For inspecting an existing PDF, pypdf is still the right tool. For filling a fillable PDF programmatically, the DullyPDF API is usually faster to integrate and produces output that renders consistently across PDF readers, including Adobe Reader.

Can I call this from AWS Lambda or Cloud Run?

Yes. Because the call is plain HTTPS with no native dependencies, every serverless Python runtime works. No need to bundle pdftk or LibreOffice.

How do I know what JSON keys to send?

Each published endpoint exposes a downloadable schema with the exact field names you reviewed during template setup. The schema is template-scoped and only changes when you intentionally republish.

Async support?

Yes — call the same endpoint from httpx.AsyncClient or aiohttp. The endpoint is just an HTTPS POST and is async-runtime agnostic.

Docs for PDF Fill API for Python

Use these docs pages to verify the exact DullyPDF behavior behind pdf fill api for python before you ship it as a repeat workflow.

Related routes for PDF Fill API for Python

These adjacent workflow pages cover nearby search intents teams compare while evaluating pdf fill api for python.