API DOCUMENTATION
From a PDF template to a filled file.
FormRail fills existing AcroForm fields. Start by checking your template. Inspection and validation are free within the request limits.
Download the example template · See its filled output · Download the n8n workflow
1. Get a key
Open your workspace and create an API key. Send it as Authorization: Bearer YOUR_KEY. Keys start with vf_. Keep them on your server or in your workflow platform’s credential store. Never put them in a public web page.
2. Inspect, validate and fill
The API accepts JSON. The pdf property is the file bytes encoded as base64, without a data-URL prefix. Send field values as strings, booleans or arrays of choice strings. Inspection returns the exact names inside the PDF, not names from a browser’s HTML.
import fs from 'node:fs/promises';
const base = 'https://formrail.voltenworks.com/v1';
const pdf = (await fs.readFile('template.pdf')).toString('base64');
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.FORMRAIL_API_KEY}`,
};
const inspect = await fetch(base + '/inspect', {
method: 'POST', headers, body: JSON.stringify({ pdf }),
});
const template = await inspect.json();
if (!inspect.ok || !template.compatible) throw new Error(JSON.stringify(template));
const body = {
pdf, templateHash: template.templateHash,
mapping: { project: 'ProjectName', ready: 'Ready' },
data: { project: 'September installation', ready: true },
flatten: true,
};
const check = await fetch(base + '/validate', {
method: 'POST', headers, body: JSON.stringify(body),
});
const validation = await check.json();
if (!check.ok || !validation.valid) throw new Error(JSON.stringify(validation));
const filled = await fetch(base + '/fill', {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': 'job-1042-revision-1' },
body: JSON.stringify(body),
});
if (!filled.ok) throw new Error(await filled.text());
await fs.writeFile('filled.pdf', Buffer.from(await filled.arrayBuffer()));The sample uses the linked template. Your PDF will have its own field names. Mapping is optional: omit it to use exact PDF field names directly. When using a mapping, include the templateHash from inspection. Keep the PDF, mapping and hash together in your integration. FormRail does not host your templates.
Endpoints
| POST endpoint | Response | Credits |
|---|---|---|
/v1/inspect | Compatibility, fingerprint, pages, field types and choices | 0 |
/v1/validate | Compatibility, validity and all detected field errors | 0 |
/v1/fill | Binary application/pdf, or a JSON error | 1 per successful fill |
Inspect and validate return HTTP 200 for a parsed report, including compatible: false or valid: false. Check those flags. Fill returns 422 for invalid values. Its error response includes issues with a code, message and field name where applicable.
Retries and credits
Every fill requires an Idempotency-Key of 8 to 128 letters, numbers, underscores or hyphens. Use one key per logical output. Repeat the identical JSON body with the same key after a timeout. A successful replay regenerates the file from your input and uses zero additional credits. Changed input with the same key returns 409 idempotency_conflict. Keep property ordering stable when retrying.
A failed fill refunds its credit automatically. Correct the error and use a new key. Abandoned requests are recovered after two minutes when you next make a request or open your account. A request still running returns 409. Wait before retrying. Do not create a new key solely because a response was lost.
Responses include X-Request-Id; successful fills also include X-Credits-Used and Idempotency-Replayed. Your dashboard shows hashed request receipts, not your supplied keys or documents.
Limits and compatibility
- 2 MiB input PDF, 3 MiB JSON body, 4 MiB output, 50 pages and 200 fields.
- 30 total requests per minute per account, with at most two concurrent operations. Paid fills also have a 20-per-minute limit. HTTP 429 means slow down.
- Parsing and rendering have an 8 second worker deadline. Decoded streams are capped at 8 MiB each and 64 MiB total allocations, with a separate worker heap limit.
- Text, checkboxes, radio groups, dropdowns and list fields. Every rendered list option must fit in the field.
- Filled text uses Noto Sans, between 8 and 12 points. Supported glyphs include Latin, Greek and Cyrillic. CJK, emoji and unsupported characters return a field error. Review the output before delivery.
- Required fields must have values. Read-only fields cannot be changed. Empty strings clear optional text or choices; false clears a checkbox.
- Set
flatten: trueto paint the fields into the page and remove the interactive widgets. The API defaults to keeping fields editable. - No XFA, encrypted files, signature fields, JavaScript/actions, attachments, scans, OCR or arbitrary layout editing. Rich text, comb, password and file-select fields are unsupported.
Useful errors
| Code | Next step |
|---|---|
no_fillable_fields | Add AcroForm fields in a PDF editor. Printed text and scans are not fields. |
xfa_unsupported | Export a standard AcroForm PDF from its authoring tool. |
unknown_field | Use the exact field name from inspection or update your mapping. |
template_changed | Inspect the new PDF and review its mapping before filling. |
text_does_not_fit | Shorten the value or enlarge the field. FormRail will not silently clip it. |
unsupported_character | Use characters supported by the bundled font. |
credits_exhausted | Add a prepaid pack or wait for your next paid period. |
decoded_stream_limit | Export a simpler PDF. Its compressed object streams exceed the processing limit. |
n8n
Import the downloadable workflow. Its sample step downloads the example PDF, a Code node reads the binary using this.helpers.getBinaryDataBuffer(0, 'data'), and the HTTP Request node sends JSON to FormRail. Choose a Header Auth credential named Authorization with value Bearer YOUR_KEY. Set the response format to File. The returned binary can go to your storage or email node.
For your own template, download it from Drive or another source, inspect its fields first, and replace the example data. Do not convert the whole JSON request to a binary file. Only the PDF bytes go in the base64 pdf property. FormRail does not send an email for you.
Data handling
Documents and field values are processed in memory, never stored in the application database or sent to analytics. Account records contain credits, API key hashes, payment references, fixed error codes, timing and usage counts. See the privacy policy for providers and attribution details.