PdfForms is an AGPL-licensed PDF AcroForm tool to inspect fields, fill from JSON/FDF/XFDF/CSV, regenerate appearance streams, flatten forms, validate field values, and run batch ZIP workflows.
- Minimal white-themed playground: upload a PDF on the home page, fill fields, and download — no login wall.
- Field inspection (
/v1/inspect) with name, type, options, required, max length, value, page, and bbox. - Auto-generated form UI in the Next.js playground.
- JSON/FDF/XFDF import and schema-driven validation.
- Fill with appearance regeneration toggle and flatten option.
- Batch ZIP + CSV mapping fill flow (
/v1/batch). - Signed artifact download URLs with TTL.
- Web: Next.js 15 + Tailwind 4 + shared workspace packages.
- Worker: Python 3.12 + FastAPI +
pypdf+pdfcpu+qpdf.
- Install Node 22+, pnpm 10+, Python 3.12+.
- Install JS deps:
pnpm install- Install worker deps:
cd apps/worker
python -m pip install -e .[dev]- Start worker:
cd apps/worker
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000- Start web:
pnpm --filter @pdf-forms/web dev --port 3000- Open
http://127.0.0.1:3000.
The web app proxies API calls to /api/worker/* (configure with WORKER_PROXY_URL, default http://127.0.0.1:8000). You can override with NEXT_PUBLIC_WORKER_URL for direct cross-origin access.
Legal: /terms, /privacy, /disclaimer, and LICENSE (AGPL-3.0). See LEGAL.md for an overview. Hosted use is subject to liability limitations and indemnity in the Terms; obtain your own legal advice for regulated or commercial use.
SEO landing routes include /w9-fill-online, /i9-fill-online, /pdf-form-fill, /pdf-flatten, /fdf-to-pdf, and /xfdf-to-pdf.
docker compose up --buildWeb: http://localhost:3000 (API proxied at /api/worker)
Worker: http://localhost:8000/healthz (also exposed on the host for debugging)
python apps/worker/scripts/verify_hosted.py \
--web-url https://pdf-forms.your-domain.tld \
--api-url https://api.pdf-forms.your-domain.tld/healthzThe command fails non-zero unless both hosted endpoints return 2xx and both TLS certificates validate.
You can also set PDF_FORMS_WEB_URL and PDF_FORMS_API_URL env vars and run python apps/worker/scripts/verify_hosted.py.
Section 14 release-gate runbook: docs/SECTION14_RUNBOOK.md.
Release artifact verification helper: python apps/worker/scripts/verify_release_artifacts.py --repo <owner>/acroform-filler --tag <vX.Y.Z>.
A1 evidence helper: python apps/worker/scripts/generate_a1_evidence.py.
Section 14 local audit helper: python apps/worker/scripts/run_section14_local.py --skip-hosted.
Section 14 verdict report: python apps/worker/scripts/section14_report.py.
Hosted URL variable helper: python apps/worker/scripts/configure_hosted_urls.py --web-url <...> --api-url <...>.
Qualified-PR helper (gated): python apps/worker/scripts/create_section14_pr.py.
Preview evidence helper: python apps/worker/scripts/record_preview_evidence.py --screenshot <path>.
- Password inputs are request-scoped and not persisted.
- Job artifacts are ephemeral and purged by TTL.
- API errors use explicit codes (e.g.
401_PDF_PASSWORD_REQUIRED,409_XFA_NOT_CONVERTIBLE).
