API reference
Fill any PDF from your own code
Two endpoints. Upload a document the API has never seen — a government form, a carrier PDF, a scan — and it returns the fields it found. Send values for those fields and it returns the filled document.
The difference from most form-filling APIs is that there is no per-document template to configure first. You do not map a schema, name fields, or prepare a template before the first call. Extraction runs on whatever you post, including scanned pages via OCR.
Authentication
Create a key in Settings → API keys. The key is shown once and stored only as a hash, so it cannot be recovered later — if you lose it, revoke it and make another. Send it as a bearer token on every request.
Authorization: Bearer filly_live_...Keys are scoped to one account. Revoking a key takes effect immediately and keeps its last-used timestamp, which is what you want when you suspect one has leaked.
1. Upload a document
POST /api/v1/forms — multipart form data with a file part. PDF or DOCX, up to 4 MB, up to 100 pages.
curl -X POST https://getfilly.app/api/v1/forms \
-H "Authorization: Bearer $FILLY_API_KEY" \
-F "file=@loan-application.pdf" \
-F "name=Loan application"The response carries the field ids you fill against:
{
"id": "1dcc72bd-33ef-4147-9bd1-13a150b6af7a",
"name": "Loan application",
"file_type": "pdf",
"reused": false,
"fields": [
{ "id": "f_0_full-legal-name", "label": "Full legal name",
"type": "text", "required": true, "profile_key": "first_name" },
{ "id": "f_1_date-of-birth", "label": "Date of birth",
"type": "date", "required": true },
{ "id": "f_2_tax-identification-number", "label": "Tax identification number",
"type": "text", "required": false }
]
}Uploading the same file twice returns the original form rather than creating a second one — reused is true and no analysis is charged or re-run. Retries and re-runs of your script are therefore safe, and any corrections you have made to that form stay attached to it.
2. Fill it
POST /api/v1/fills — JSON. Keys are the field ids from step 1; unknown ids are ignored.
curl -X POST https://getfilly.app/api/v1/fills \
-H "Authorization: Bearer $FILLY_API_KEY" \
-H "content-type: application/json" \
-d '{
"form_id": "1dcc72bd-33ef-4147-9bd1-13a150b6af7a",
"values": {
"f_0_full-legal-name": "Dana Whitfield",
"f_1_date-of-birth": "1988-04-02"
}
}'{
"id": "2ab4d145-9baa-486d-86f7-5b4d2c352be6",
"form_id": "1dcc72bd-33ef-4147-9bd1-13a150b6af7a",
"document_base64": "JVBERi0xLjcKJc...",
"content_type": "application/pdf",
"filled_fields": 2,
"total_fields": 20
}The document comes back inline, base64-encoded, so one round trip is enough. To fill from a saved client profile instead of explicit values, send client_id in place of values and the AI maps that profile onto the form.
Limits and latency
Worth knowing before you design around it:
- Analysis takes roughly 20–30 seconds for a document the API has not seen, because a model reads it. Filling takes roughly 10–20 seconds. This suits batch and background work; it is too slow to sit inside a synchronous web request.
- Repeat uploads of the same file are fast (~3 seconds) — they short-circuit on a content hash and skip analysis entirely.
- 4 MB per upload, 100 pages per PDF. Larger documents must be split.
- Rate limits: 20 uploads and 60 fills per minute per account.
- Every fill counts against your plan, the same as one made in the browser. The free plan includes 10 fills per month and 10 saved forms, with no card required — enough to evaluate the API properly.
What it will not do
- It is not a PDF editor. No redaction, page reordering, or format conversion through the API — it fills forms and returns the document.
- Extraction is a model reading a document, not a parser. It is usually right and sometimes not. Anything consequential should be reviewed before it is filed. Field confidence is surfaced in the app; treat API output as a draft.
- Some documents fail placement. Where values cannot be positioned reliably the fill returns HTTP 422 with
code: "placement_failed"rather than silently producing a document with text in the wrong place. - No webhooks or async jobs yet. Both calls are synchronous. If that blocks you, say so — it is the most likely next addition.
Errors
| Status | Meaning |
|---|---|
| 400 | Malformed request, unsupported file type, or a PDF over 100 pages. |
| 401 | Missing, malformed, or revoked API key. |
| 402 | Plan limit or credits exhausted. |
| 404 | The form or client id does not belong to this account. |
| 422 | Analysis or placement could not complete for this document. |
| 429 | Rate limited. |
| 502 | The analysis model failed. Retrying is reasonable. |
Getting started
Create an account, generate a key in Settings → API keys, and the free plan’s 10 monthly fills are enough to try both endpoints end to end. For higher volume or a per-document rate, get in touch — API pricing is being set now and early integrators shape it.