How to pre-fill PDF forms with AI agents using SimplePDF

Profile picture of Benjamin André-Micolon
A Prefill API service fills a PDF application form (full name, email, date of birth, gender, signature) which is then approved

An AI agent can read a customer email, a database row, or a previous submission and work out what belongs in a form. What an agent should not do is submit a form on its own. The prefill API lets your agent prepare a fully filled-in PDF and hand it to a person to review, correct, and submit: the agent does the tedious part, a human stays in the loop for the decision that matters.

This keeps completion rates high, the recipient opens a document that is already done, not a blank form, while keeping a human accountable for what gets submitted.

This guide talks about an AI agent, but the prefill API is just an HTTP (REST) API. Any system that can make an HTTP request can use it: an AI agent, a backend job, a workflow automation, or a CRM integration. See the API documentation for a human-readable reference, or the OpenAPI spec to import into your tools or generate a client. Both document every endpoint and field.

How it works

A prefill is a set of field values that lives in your own storage (S3, Azure Blob Storage, or SharePoint), never on SimplePDF. You create a prefill through the API, upload the values straight to your storage, and share a link. When the recipient opens the link, the editor reads the values from your storage and renders the filled-in document for review.

Prefill data flow
Field values go to your storage, never to SimplePDF
    Your agent              SimplePDF              Your storage          Your recipient
   ┌────────────┐         ┌────────────┐        ┌─────────────────┐    ┌────────────┐
   │   .----.   │         │            │        │                 │    │  ( ^_^ )   │
   │  [ o  o ]  │         │  SimplePDF │        │  Your storage   │    │   /| |\    │
   │  [  __  ]  │         │     API    │        │ S3/Azure/ShareP │    │    | |     │
   │   '-||-'   │         │            │        │                 │    │   _/ \_    │
   │  a robot   │         │            │        │                 │    │  a human   │
   └──────┬─────┘         └──────┬─────┘        └────────┬────────┘    └──────┬─────┘
          │                      │                       │                    │
          │  1. POST /prefills   │                       │                    │
          │ ───────────────────> │                       │                    │
          │   upload + embed_url │                       │                    │
          │ <─────────────────── │                       │                    │
          │                      │                       │                    │
          │  2. upload the prefill blob (field values never reach SimplePDF)  │
          │ ───────────────────────────────────────────> │                    │
          │                      │                       │                    │
          │                      │   3. opens embed_url; editor loads values  │
          │                      │                       │ <──────────────────│
          │                      │                       │                    │
          │                      │  4. reviews, edits if needed, then submits │

   ───────────>  API call (identifiers + links only, no field values)
   ───────────────────────────────────────────>  Direct upload / download (bypasses SimplePDF)

Because the values are written directly to your storage, the field values never reach SimplePDF. The API only ever handles identifiers and links.

Before you start

To follow this guide you need:

The examples below use curl; replace $COMPANY with your company identifier and $API_KEY with your API key.

Step 1: List the fields you can pre-fill

Ask the document which fields exist and what they accept. Each field has a stable id you will reference in the prefill, a type, and (for constrained fields) the allowed options.

Get the field schema
GET /documents/{document_id}/fields
curl https://$COMPANY.simplepdf.com/api/v1/documents/$DOCUMENT_ID/fields \
  -H "Authorization: Bearer $API_KEY"

# Response
{
  "data": [
    { "id": "f_abc1455", "name": "first_name", "type": "text", "options": null },
    { "id": "f_9k2m7d3q", "name": "plan", "type": "checkbox", "options": ["checked", "xchecked", "unchecked"] },
    { "id": "f_5t8w0r6z", "name": "logo", "type": "picture", "options": null }
  ]
}

A field's name, and whether it is required, has a default_value, or is read_only, are configured from your dashboard. See configure document fields. Read-only fields keep their configured value and ignore anything you send in the prefill.

Step 2: Create a prefill

Create the prefill to get two things back: an upload object that tells you exactly where and how to send the values, and an embed_url the recipient will open.

Create a prefill
POST /documents/{document_id}/prefills
curl -X POST https://$COMPANY.simplepdf.com/api/v1/documents/$DOCUMENT_ID/prefills \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "context": { "agent": "intake-bot", "user_id": "u_123" } }'

# Response
{
  "id": "05666d45-96d0-42ce-b24b-f1f1af228f57",
  "upload": { "type": "presigned_put", "url": "https://your-storage/...", "method": "PUT", "headers": { "Content-Type": "application/json" } },
  "embed_url": "https://$COMPANY.simplepdf.com/documents/$DOCUMENT_ID?prefill=05666d45-..."
}

The optional context is correlation metadata (for example which agent produced the prefill). It is delivered with the submission so you can tie it back to your own records. Keep it free of sensitive data: the field values themselves go in the blob, never here.

Step 3: Upload the prefill values to your storage

Send a JSON blob of shape { "fields": [{ "id", "value" }] } using the upload object from the previous step. Each id comes from Step 1; each value is a string for text and checkbox fields, or a base64 data URL for signature and picture fields.

Upload the prefill blob
Send it with the upload method and url
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "fields": [
      { "id": "f_abc1455", "value": "Bob" },
      { "id": "f_9k2m7d3q", "value": "checked" },
      { "id": "f_5t8w0r6z", "value": "data:image/png;base64,iVBORw0KGgo..." }
    ]
  }'

Notes on values:

  • If the field lists options (in GET /fields), the value must be one of those options. This covers checkboxes, dropdowns, and radios.
  • Otherwise, the value is a plain string (text fields) or a base64 data URL such as data:image/png;base64,... (signature and picture fields). Signatures look best as a transparent PNG at roughly a 3:1 aspect ratio (for example 1200x400).
  • Unknown ids are ignored, and fields the document marks read-only keep their existing value.

If the upload.type is presigned_post (S3 form upload) send the listed fields as multipart form data instead of a PUT body; for graph_upload_session (SharePoint) also set Content-Length and Content-Range to the blob's byte length.

Step 4: Send the link for review

Share the embed_url with the person who should review and submit. They open a document that is already filled in, make any corrections, and submit. You can open it standalone or embed it in your own app.

To get notified when they submit, configure a webhook: the submission event includes the context you set in Step 2.

Keeping prefills tidy

Prefills are kept until you remove them, so you can re-share or audit a link. Delete one when you no longer need it:

Delete a prefill
DELETE /documents/{document_id}/prefills/{prefill_id}
curl -X DELETE https://$COMPANY.simplepdf.com/api/v1/documents/$DOCUMENT_ID/prefills/$PREFILL_ID \
  -H "Authorization: Bearer $API_KEY"

Prefill creation and deletion are recorded in your audit logs.

That's it! Your agent can now pre-fill a PDF, and a person reviews and submits it with a human in the loop.

If you have any questions, feel free to reach out to support@simplepdf.com

You may also be interested in