Skip to content
Start free

Generate PDFs via API

Open in ClaudeOpen in ChatGPT

DocSpring generates PDFs and Word documents by filling your templates with submission data. Templates can be PDFs that you annotate in the Template Editor, fully custom HTML/CSS layouts that you host in DocSpring, or Word documents with tags in them.

POST /api/v2/templates/{template_id}/submissions

A submission for a PDF template must include:

  • data: Field values that match your template schema. Date fields take YYYY-MM-DD dates (or NN/NN/YYYY in your template’s date format, when a PDF template’s “Parse dates using the template’s date format” setting is on).

Optional parameters:

  • test: Use true for free, watermarked PDFs while building your integration. Defaults to false. Live PDFs use credits; a request your balance can’t cover returns a 402 insufficient_credits error (Credits & Rate Limits).
  • metadata: Map of values you want echoed back in webhooks.
  • editable: Keep the resulting PDF fillable or flatten the form fields. See Editable PDFs.
  • expires_in: Number of seconds until the submission expires. DocSpring then deletes the PDF, the submission data and metadata, and the submitter’s IP address, browser and location. A submission that fails is kept for at least 48 hours.
  • password: Encrypt the generated PDF with this password. It’s never returned: the submission’s has_password says whether it’s set.
  • output_formats: The files to make: pdf, docx for a Word document and odt for an OpenDocument file (Word templates only), and png for an image of each of the PDF’s pages (see Images of the Pages). Defaults to ["pdf"], or a Word template’s output format (see Output Format).
  • field_overrides: Change field settings for this submission only, by field name, such as {"name": {"required": false, "font_size": 9}}. Setting names are snake_case.
  • signature_requests: Ask people to fill in fields and sign before the PDF is generated. See Create Signature Requests.

Two options are query parameters, not part of the JSON body:

  • version: Choose draft, latest (the default), or a published version such as 1.2.3 (or 1 for the latest 1.x.x).
  • wait: Choose between synchronous and asynchronous processing (for example, ?wait=false). See Processing Modes.

Data that doesn’t match the template’s fields returns a 422 with an invalid_data error. The submission is still saved with its errors, so you can find it in DocSpring: the error’s submission_id is its ID.

To check a request without creating anything, send the same query and body to POST /api/v2/templates/{template_id}/submissions/validate. It runs the same checks without saving a submission, generating a PDF or using credits. The response’s valid says whether creating the submission would succeed, and when it’s false, error is the error that creating it would return.

Submissions sent to sync.api.docspring.com wait for processing and return the PDF’s download_url and permanent_url in the response’s files.pdf. Switching wait=false or using the asynchronous domain returns immediately with a pending submission. See Sync vs. Async Processing for the time limit, status checks, and webhook guidance.

By default, DocSpring “flattens” generated PDFs into static text, so the fields cannot be changed. You can instead generate PDFs that keep editable form fields (AcroForm fields). Only Text and Check fields become form fields; other display types are always static.

There are two ways to control this:

  • Per submission: Set editable: true in your submission request to make every field editable, or editable: false to flatten every field. An explicit value always takes precedence over the per-field option and the template setting below.
  • Per field: Enable the “Editable” option on an individual field in the Template Editor. That field is rendered as an editable form field whenever the submission does not set the editable option.

Some templates (for example, older templates) have the “Generate Editable PDFs” template setting turned on. For these templates, every field is editable unless the submission sets editable: false.

Signed PDFs are always static. When a submission has a signature request that asks someone to sign or initial, every field is flattened, whatever the submission, the template and the fields say. Anyone holding an editable signed PDF could change a value and it would still look like the signed original. Signature requests that only collect values keep the options above.

Add png to output_formats to also get a PNG image of each page of the PDF. The images are of the PDF, so png adds pdf if you leave it out:

{
"data": { "first_name": "Jane" },
"output_formats": ["pdf", "png"]
}

The images are made with the PDF, and the submission is processed once both exist. They’re in the submission’s files.png.pages, in page order (pages[0] is page 1), each with its width and height in pixels, a download_url and a permanent_url. The images are 140 DPI: a US Letter page is 1190 x 1540 pixels. If the images can’t be made, you still get the PDF: the submission is processed, and files.png has the state error with an error_message that says why.

To add the images to a submission that has already been processed, send {"formats": ["png"]} to POST /api/v2/submissions/{submission_id}/generate_files. A Word template’s submission that made only a Word document gets its PDF first. On sync.api.docspring.com the request waits for the new files. Otherwise each new file is in files with the state pending until it’s been made, then processed, or error with an error_message. The submission itself stays processed.

  • Images can be made of PDFs with up to 100 pages. A request for png is refused when the template, or for generate_files the PDF, has more pages. An audit trail adds pages, so a PDF can still go over the limit: then only files.png shows the error.
  • A password-protected PDF can’t have images of its pages: they would show what the password protects.

Need to create many PDFs at once? Use the batch endpoint to submit up to 50 requests together. Each entry can target a different template, switch between test/live, and specify its own metadata.

The form library has ready-made templates for common forms, such as IRS Form W-9. Each form’s page shows its template ID. Send submissions to that template ID with your own API token, and they go into your account:

  • The submissions and their PDFs are in your account, with your other submissions, and count toward your account’s usage like your other PDFs. No other account can see them. The form doesn’t count toward your plan’s template limit.
  • We keep the form up to date. Each request uses the latest version we’ve published, unless you set the version query parameter to one of its published versions. You can’t fill the draft we’re working on: version=draft returns a 404.
  • Our settings for the form don’t apply to your submissions: no webhook URL, Slack or email notifications, redirect URL or PDF encryption, and signers can’t download the PDF from the signing page. Submissions expire as your account’s default template settings say, and embedded signature requests only load on the sites in their Embed Domains.
  • Your account’s webhooks get the submission and signature request events (submission.*, and submission_data_request.*, or signature_request.* on a version 4 webhook). A webhook limited to some of your templates or folders doesn’t, unless it’s also limited to the API token you used. Your storage integrations upload the PDFs, except integrations limited to some of your templates or folders.
  • If we take a form out of the library, you can’t create new submissions with it. Your earlier submissions stay in your account.

To change the form or use your own settings, open it in the template editor (from the form’s page, or from one of your submissions) and click Copy to account. The copy is your own template, with its own template ID, and we don’t update it. If you find a problem with one of our forms, click Send feedback in the editor.

Batch requests and signature requests work the same way, except that DocSpring doesn’t email a form’s signers: leave send_email out, and send each person their link yourself (Create Signature Requests). The form library is currently only available to accounts in our US region.