PDF Form Filler
Documents skill, available on Zeplik
PDF Form Filler is a ready-to-run documents skill on Zeplik. You read the fields, fill them in the sandbox and hand back the finished PDF, and never hand the user a script. Ask in plain language and Zeplik applies the skill's method for you inside the conversation, on whichever AI model you prefer.
The PDF Form Filler skill loads automatically when your request matches it, or you can invoke it directly by typing /pdf-forms in any chat. It works with attachments, connectors, and any model that supports the task, so you get the same expert method every time without setting anything up.
What the PDF Form Filler skill can do
- Fill an AcroForm PDF and hand back the completed file, signature left blank
- Map each field to the right value from your details, asking only for what can't be inferred
- Place values on flat or scanned forms by coordinate, including per-character comb boxes
- Render the filled pages back and check every value sits on its line before delivering
Try these prompts on Zeplik
Pick a prompt to open it in the Zeplik app. If you are not signed in yet, your prompt is waiting for you the moment you do.
How the PDF Form Filler skill works
PDF Form Filling (perform, do not advise)
You FILL the form yourself. Every PDF the user uploaded in this conversation is
already staged in the sandbox working directory under its (sanitized) filename:
characters outside A-Za-z0-9._- become _, so Form T1 (2025).pdf is staged
as Form_T1__2025_.pdf. List the directory if unsure:
import os; print(sorted(os.listdir(".")))
The canonical workflow:
- Inspect the form to learn what kind it is and what fields exist.
- Ask the user only for the values you genuinely cannot infer - in one batched question, not one field at a time.
- Fill with
code_execution(python), using the preinstalled toolchain: pypdf, pymupdf (fitz), pikepdf, pdfplumber, pytesseract (+ tesseract binary), reportlab, Pillow. - Verify in the same run - re-read the values back out, and render the filled pages to PNG to confirm the text sits on its line and inside its box.
export_filethe finished PDF to hand the user a download card.
The sandbox has NO internet: never try pip install; everything you need is
preinstalled. Never paste a script for the user to run locally.
Step 1 - Inspect (always do this first)
import fitz, pikepdf
doc = fitz.open("form.pdf")
rows = []
for page in doc:
for w in page.widgets():
rows.append((page.number + 1, w.field_name, w.field_type_string,
repr(w.field_value), [round(v) for v in w.rect]))
print(f"pages={doc.page_count} widgets={len(rows)}")
for r in rows: print(r)
with pikepdf.open("form.pdf") as pdf: # XFA check
acro = pdf.Root.get("/AcroForm")
print("XFA:", bool(acro and "/XFA" in acro))
This tells you which of three cases you are in:
| Result | Case | How to fill |
|---|---|---|
| widgets found, XFA false | AcroForm | Step 2A - native field fill |
| no widgets | Flat / scanned | Step 2B - place text at coordinates |
| XFA true | XFA | Step 2C |
Cryptic field names (Text1, Field_7) are normal. Render the page and read
the printed labels next to each widget rectangle rather than guessing from the
name:
pix = doc[0].get_pixmap(dpi=150); pix.save("page1.png")
You can look at that PNG yourself - match each w.rect to the label printed
beside it. For a scanned form with no text layer, OCR it to read the labels:
import pytesseract
from PIL import Image
print(pytesseract.image_to_string(Image.open("page1.png")))
Step 2A - AcroForm (native fields)
fitz writes real appearance streams, so the values render correctly in every viewer. Prefer it:
import fitz
values = {"topmostSubform[0].Page1[0].f1_01[0]": "Jane Okonkwo"} # field_name -> value
doc = fitz.open("form.pdf")
filled = 0
for page in doc:
for w in page.widgets():
if w.field_name in values and w.field_type_string != "Signature":
w.field_value = values[w.field_name]
w.update(); filled += 1
doc.save("form_filled.pdf")
print("filled", filled, "of", len(values))
Checkboxes take the widget's own on-state, not "Yes" - read
w.button_states() and set w.field_value to one of the returned on-values.
Dropdowns/radio groups must be set to an existing choice; print
w.choice_values first.
pypdf is the fallback if a widget refuses to update:
from pypdf import PdfWriter
writer = PdfWriter(clone_from="form.pdf")
writer.set_need_appearances_writer(True)
for page in writer.pages:
writer.update_page_form_field_values(page, values)
writer.write("form_filled.pdf")
Step 2B - Flat form (no fields at all)
Locate each label with a text search, then place the value to the right of it on the same baseline. Never eyeball absolute coordinates on the first try:
import fitz
doc = fitz.open("form.pdf")
page = doc[0]
hits = page.search_for("Full name") # list of rects for that label
if hits:
r = hits[0]
page.insert_text(fitz.Point(r.x1 + 8, r.y1 - 2), "Jane Okonkwo",
fontsize=10, fontname="helv")
doc.save("form_filled.pdf")
Comb fields (one printed box per character, e.g. a postal code) - measure the run of boxes once and step across it:
x0, x1, y = 180.0, 300.0, 412.0 # left edge, right edge, baseline of the comb
text = "K1A0B1"
step = (x1 - x0) / len(text)
for i, ch in enumerate(text):
page.insert_text(fitz.Point(x0 + step * i + step / 2 - 3, y), ch,
fontsize=11, fontname="helv")
If the form is a scan with no text layer, page.search_for returns nothing -
OCR with position data to find the labels:
import pytesseract
from PIL import Image
d = pytesseract.image_to_data(Image.open("page1.png"),
output_type=pytesseract.Output.DICT)
Remember the PNG was rendered at 150 dpi while PDF coordinates are 72 dpi:
divide OCR pixel coordinates by 150/72 before using them with fitz.
Step 2C - XFA
Dynamic XFA forms (common in older government/bank PDFs) carry their fields in an XML payload that this toolchain cannot render or fill. Say so plainly: tell the user the form is XFA, that it opens correctly only in Adobe Acrobat Reader, and offer the alternative you CAN deliver - the complete field-by-field list of what to type where, so they can fill it in Reader in one pass. Do not silently produce an unfilled or half-filled file.
Step 3 - Verify before you deliver
Never declare done without reading your own output back:
import fitz
doc = fitz.open("form_filled.pdf")
for page in doc:
for w in page.widgets():
if w.field_value: print(w.field_name, "=", repr(w.field_value))
doc[0].get_pixmap(dpi=150).save("check1.png")
Look at check1.png. Every value must sit on its line and inside its box - not
riding above it, not spilling past the right edge, not overlapping printed
text. Shift the coordinates and re-run until it is right. For a flat form this
visual check is the only real verification; do not skip it.
Step 4 - Deliver
export_file("form_filled.pdf"), then state in chat:
- the values you filled, field by field (so the user can check them at a glance)
- anything you left blank and why
- the signature line, explicitly: it is blank and they need to sign it
Rules
- Never fill a signature field, and never paste in a signature image unless the user supplied one and asked for it. Placing an image is a visual mark, not a certified digital signature - say so when you do it.
- Never invent a value. A wrong number on a tax or claim form is worse than a blank one. If you cannot infer it, ask.
- Never hard-code or echo a national ID, SIN/SSN, bank account, or card number into a script comment or a summary. Fill it if the user gave it, then refer to it as "the account number you provided" - do not repeat it back.
- Ask for every missing value in ONE batched question, listing them as a numbered checklist.
- If the user's details arrive as a file (profile.json, a CSV, an ID scan), read it in the sandbox rather than asking them to retype anything.
Zeplik output presentation
Present the final deliverable as a single polished artifact: clear headings, tables where the content is tabular, fenced code where it is code. Lead with the deliverable itself; keep process commentary to a single short line. If the skill produced multiple files or sections, end with a compact list of them with one-line purposes.
How to use the PDF Form Filler skill
Sign in to Zeplik
Create a free Zeplik account or sign in. New accounts start with free credits, so you can try the PDF Form Filler skill right away.
Describe your documents task
Ask in plain language, or type /pdf-forms to invoke the skill directly. Zeplik recognizes the PDF Form Filler skill and applies its method.
Review and refine the result
Zeplik returns a clear, structured answer. Ask follow-ups in the same chat to refine it or take the next step.
Source and credit
- Author
- zeplik (operational rewrite; originally adapted from davila7/claude-code-templates, MIT)
- License
- MIT
Adapted from the open-source davila7/claude-code-templates project and tuned to run natively on Zeplik. View source on GitHub.
Frequently asked questions
- What is the PDF Form Filler skill?
- PDF Form Filler is a ready-to-run documents skill on Zeplik. You read the fields, fill them in the sandbox and hand back the finished PDF, and never hand the user a script. Ask in plain language and Zeplik applies the skill's method for you inside the conversation, on whichever AI model you prefer.
- How do I use PDF Form Filler on Zeplik?
- Sign in to Zeplik and ask in plain language, or type /pdf-forms in any chat to invoke it directly. The skill applies its method and returns a result you can refine in the same conversation.
- Which AI model does the PDF Form Filler skill use?
- Any model you choose. Zeplik works across every model in one chat, so the PDF Form Filler skill runs on your preferred model for the task.
- Where does the PDF Form Filler skill come from?
- The PDF Form Filler skill is adapted from the open-source davila7/claude-code-templates project (MIT) and tuned to run natively on Zeplik. The original source is linked on this page.
- How much does the PDF Form Filler skill cost?
- Using the skill is free to start. You only spend Zeplik credits when the assistant runs, and new accounts begin with free credits.
Related documents skills
- Excel & Spreadsheet BuilderUse when the user wants to create, edit, analyze or format spreadsheets (.xlsx, .csv, .tsv), preserving formulas, references and formatting via openpyxl and pandas.
- File ConversionUse when converting file formats -- csv/json, markdown/word, images, audio, ebooks -- via artifact or exact tool steps. Not for spreadsheet work (use spreadsheet) or PDF edits (use pdf-processing).
- JSON CanvasProduces valid JSON Canvas 1.0 .canvas files with nodes, edges, groups, and connections. Not for rendered flowcharts in Markdown (use diagram).
- PDF ReaderUse when a PDF must be marked up - highlights, notes, APPROVED/DRAFT/CONFIDENTIAL stamps, redaction, a signature image. You apply it in the sandbox and never hand the user a script.
- PDF ToolkitUse when something must be done to a PDF - extract text, tables or images, split, merge, crop, rotate, reorder, compress, repair, OCR. You do it in the sandbox and never hand the user a script.
- Word Document BuilderUse when the user wants to read, create or edit Word documents (.docx), especially when formatting or layout fidelity matters; uses python-docx plus a render script for visual checks.
More on Zeplik
Try PDF Form Filler on Zeplik
Every model, one chat. Bring the PDF Form Filler skill into your next conversation and let the assistant do the work.