File Upload
Uploading a file to Formtorch takes two steps: the browser asks for an upload policy, POSTs the file straight to storage with it, then submits the form referencing the uploaded file by ID.
Uploads must be enabled for the form, and are available on Starter and Pro. See File Uploads for limits and accepted types.
JavaScript
Request an upload policy
const file = document.querySelector("#attachment").files[0];
const intentRes = await fetch("https://formtorch.com/api/uploads/intent", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
formId: "YOUR_FORM_ID",
files: [{ name: file.name, mimeType: file.type, size: file.size }],
// turnstileToken: "...", // only if the form has captcha configured
}),
});
const { files } = await intentRes.json(); // [{ fileId, uploadUrl, fields }]POST the file to storage
Send multipart/form-data built from the returned fields. This is a POST with
a policy, not a raw PUT of the file body, and the file field must be appended
last.
const s3Form = new FormData();
for (const [key, value] of Object.entries(files[0].fields)) {
s3Form.append(key, value);
}
s3Form.append("file", file); // must be appended last
await fetch(files[0].uploadUrl, { method: "POST", body: s3Form });Submit the form with _file_ids
_file_ids maps your form’s field names to the file IDs from step 1. A field can
take a single ID or an array of them.
const formData = new FormData();
formData.append("name", "John Doe");
formData.append("email", "john@example.com");
formData.append("_file_ids", JSON.stringify({ attachment: files[0].fileId }));
await fetch("https://formtorch.com/f/YOUR_FORM_ID", {
method: "POST",
body: formData,
});Multiple files
Request a policy for every file in one intent call, upload each with its own
policy, then pass an array of IDs for that field:
formData.append(
"_file_ids",
JSON.stringify({ attachments: files.map((f) => f.fileId) })
);Field names in _file_ids must match your form’s field names, cannot start with
_, and are capped at 100 characters.
Limits and types
| Limit | Starter | Pro |
|---|---|---|
| Max size per file | 25 MiB | 25 MiB |
| Max files per submission | 10 | 10 |
| Max total size per submission | 100 MiB | 100 MiB |
| Total storage | 1 GB | 5 GB |
Accepted types are an allowlist: PDF, DOC, DOCX, XLS, XLSX, PNG, JPEG, WebP,
GIF, text/plain, and CSV. The accept attribute on the input is a client-side
hint only; Formtorch verifies the type against the file’s actual bytes when it
attaches the file.
Retrieving files
Notification emails include a signed download link per file, webhook and Zapier
payloads include a downloadUrl, and the REST API exposes
GET /v1/submissions/:submissionId/files. See
File Uploads for details.