Get Chrome extension

PDF Form API: Fill Any PDF Form from Your Code

8 min read

Most PDF tooling for developers solves generation: take a template, pour in variables, get a document. That is not the problem when the PDF already exists and comes from someone else. A visa application from an embassy, a claim form from an insurer, an onboarding packet from a government portal. You do not control the layout, the field names inside it are often things like Text42, and yet the same twelve values from your database have to land in the right boxes, every time.

This guide covers the FillWise PDF form API, an endpoint we run on top of the same engine our Chrome extension uses. You send the PDF and the source data, the engine reads the form the way a person would and returns the completed document. It shows the exact request and response, the limits, what happens when things go wrong, and what the API deliberately does not do.

Why filling existing PDFs is harder than generating new ones

The API is built around that long tail: no mapping step, the form is read at request time.

The request

One endpoint, JSON in, JSON out:

POST https://fillwise.ai/api/v1/pdf/fill
Authorization: Bearer <your key>
Content-Type: application/json
Field Type Notes
pdf string, required The form, base64-encoded. Up to 20 MB
data string Source text in any language and any shape: a CRM record, an email, notes. Up to 60 000 characters. Required unless attachments is given
attachments array, optional Up to four source documents the AI reads the data from: { "name", "mediaType", "data" } with data base64-encoded, 5 MB each. mediaType is image/jpeg, image/png, image/webp or application/pdf
pages string, optional Which pages to fill, for example "1, 3-6". All pages by default

The key comes from your account: open fillwise.ai/account, section API keys, create one, copy it once. Up to five keys can be active at a time and any of them can be revoked. X-Api-Key: <key> works as an alternative to the Authorization header.

curl

curl -sS https://fillwise.ai/api/v1/pdf/fill \
  -H "Authorization: Bearer $FILLWISE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"pdf\": \"$(base64 -w0 application.pdf)\",
    \"data\": \"Maria Petrova, born 14.03.1992 in Riga, Latvian, passport LV4482913 issued 05.02.2021, valid until 05.02.2031\",
    \"pages\": \"1-2\"
  }" > response.json

Python

import base64, json, os, requests

with open("application.pdf", "rb") as f:
    pdf_b64 = base64.b64encode(f.read()).decode()

r = requests.post(
    "https://fillwise.ai/api/v1/pdf/fill",
    headers={"Authorization": f"Bearer {os.environ['FILLWISE_API_KEY']}"},
    json={
        "pdf": pdf_b64,
        "data": "Maria Petrova, born 14.03.1992 in Riga, Latvian, passport LV4482913",
    },
    timeout=120,
)
r.raise_for_status()
result = r.json()

with open("filled.pdf", "wb") as f:
    f.write(base64.b64decode(result["pdf"]))

print(result["filled_count"], "fields,", result["mode"])

Node

import { readFile, writeFile } from "node:fs/promises";

const pdf = (await readFile("application.pdf")).toString("base64");

const res = await fetch("https://fillwise.ai/api/v1/pdf/fill", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FILLWISE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    pdf,
    data: "Maria Petrova, born 14.03.1992 in Riga, Latvian, passport LV4482913",
  }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);

const result = await res.json();
await writeFile("filled.pdf", Buffer.from(result.pdf, "base64"));
console.log(result.filled_count, "fields,", result.mode);

The response

{
  "success": true,
  "filled_count": 26,
  "mode": "acroform",
  "pdf": "<base64 of the filled PDF>"
}

mode tells you how the document was filled:

filled_count is the number of values actually written. A zero means nothing in your source data matched the form. The auto-fill is still spent in that case, because the matching did run, so check that the text really contains the values the form asks for before retrying.

Errors

Every error is JSON with error and code:

Status Code Meaning
400 BAD_REQUEST, INVALID_PDF A field is missing or malformed, or the PDF could not be read
401 MISSING_API_KEY, INVALID_API_KEY No key, or a key that was revoked
422 SCANNED_PDF_UNSUPPORTED The PDF has no text layer
429 QUOTA_EXCEEDED No auto-fills left on the account, or more than 20 requests in a minute
502 AI_FAILED The AI provider did not return a usable answer. The auto-fill is refunded, retry the request

What to check by hand

The engine reads the form and places values where they belong. It does not know your rules, so keep a review step:

Privacy

Be precise here, because PDFs are usually the sensitive documents. With the API, the PDF is sent to our server, processed in memory and returned in the same response. It is not written to disk and not kept after the response is sent. What goes to the AI provider is the list of fields the form contains plus the source data you supplied. Attached documents are read by the AI to extract the data and are handled the same way. Usage statistics record the domain, the number of fields and the timestamp, not the content.

This is different from the Chrome extension, where the PDF is parsed inside the browser and only the field list leaves it. If keeping the document on your side matters more than automation, the extension flow is the one to use.

Pricing

There is no separate API plan. Every successful fill spends one auto-fill from the account that owns the key, the same balance the extension and the account page use. The free plan starts with 20 auto-fills and adds 5 more every week, no card needed. Paid plans are 100, 500 and 2000 auto-fills per month; details at fillwise.ai/#price or in your account.

FAQ

Can I fill web forms through the API? No. The API handles PDF documents. Web forms are filled by the Chrome extension on the page itself.

Does it work with scanned PDFs? No. A scan has no text layer, so there is nothing to anchor the values to, and the request is rejected with 422. The Chrome extension can read a scanned page as an image, the API cannot yet.

How many requests can I send? 20 per minute per account. For larger batches, space the requests out. If you need more, write to us.

Is the filled PDF flattened? No. In acroform mode the fields stay interactive, so the recipient can still edit them. In flat mode the values are drawn onto the page and cannot be edited as fields.

Can I try it without code? Yes. The same engine runs in your account at fillwise.ai/account: upload a PDF, paste the data, review the result in the editor before downloading. The API is that flow without the screen.

Get started

Create a key at fillwise.ai/account, section API keys, and send your first request with the curl example above. The free auto-fills are enough to test it on a real form. If you prefer filling forms in the browser, the Chrome extension covers web forms as well as PDFs.