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.
  • API usage is metered in units, separately from what you do in the browser — see the table under Pricing for what each operation costs. The free plan includes 25 units per month with no card required: one new document plus 15 fills, enough to run both endpoints end to end.
  • Past the ceiling, usage draws on credits and returns HTTP 402 with code: "api_quota" once those run out. Browser fills on paid plans are unaffected by this ceiling.

Pricing

Usage is metered in units, so the price follows what a call actually costs to serve rather than charging a flat rate per call:

OperationUnitsWhy
Fill with values1No model call — your data, our placement engine.
Fill from client_id3Runs the mapper to match a saved profile onto the fields.
Analyse a new document10Reads the whole PDF. Re-uploads of the same file are free.

Starter

$49/mo

750 units included

≈ 750 fills, or 75 new documents

then $0.10/unit

A single integration moving steady volume.

Growth

$199/mo

3,500 units included

≈ 3,500 fills, or 350 new documents

then $0.08/unit

Production traffic across several document types.

Scale

$499/mo

12,000 units included

≈ 12,000 fills, or 1,200 new documents

then $0.05/unit

High volume, or many documents the API has never seen.

These monthly plans are not self-serve yet — talk to us and we will set one up. Being early means the pricing is still movable, and the integrations we take on now shape it. The free plan needs no card and no conversation, and the pay-as-you-go units below need no conversation either.

Or buy units as you go — no subscription

Filly credits and API units are one currency: a call spends your plan’s included units first, then draws on credits one-for-one. Buying a pack is the self-serve way onto the API — from $0.08 a unit, and the smallest pack covers 5 new documents or 50 fills.

50 units

$5

Buy
Best value

200 units

$18

Buy

500 units

$40

Buy

Two things to know before you rely on this. Credits never expire, and they are a single balance shared with the browser app — the same units pay for fills you do by hand and for the PDF tools, so this is not an API-only meter. And a pack is a one-off purchase, not a committed monthly volume. If you need either of those, or an invoice, the plans above are what to ask for.

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

StatusMeaning
400Malformed request, unsupported file type, or a PDF over 100 pages.
401Missing, malformed, or revoked API key.
402Plan limit or credits exhausted.
404The form or client id does not belong to this account.
422Analysis or placement could not complete for this document.
429Rate limited.
502The analysis model failed. Retrying is reasonable.

Getting started

Create an account, generate a key in Settings → API keys, and the free plan’s 25 monthly API units are enough to try both endpoints end to end — no card required. For higher volume or a per-document rate, see the plans above.

We use optional analytics and advertising-measurement cookies to understand product usage and see which ads bring people to Filly. This includes a masked replay of your visit — layout and clicks only, never what you type or the contents of a document. You can accept, or continue with essential-only. Privacy policy.