Documentation
File uploads
Attach files to any submission by posting multipart/form-data instead of urlencoded or JSON. Uploads must be turned on per form first - off by default so a form nobody expected to receive files can't quietly start accepting them. Requires a Pro plan or above; Free doesn't include file uploads.
Sending a file
Use multipart/form-data - the browser sets this automatically for a plain HTML form with a file input, and it is the only encoding the ingest endpoint accepts files through. JSON submissions cannot carry binary attachments.
<form action="https://send.webforms.to/wft_your_key" method="POST" enctype="multipart/form-data"> <input type="email" name="email" required /> <input type="file" name="attachment" /> <button type="submit">Send</button> </form>
const body = new FormData();
body.append("email", "ada@example.com");
body.append("attachment", fileInput.files[0]);
await fetch("https://send.webforms.to/wft_your_key", {
method: "POST",
headers: { accept: "application/json" },
body,
});A field can carry more than one file - repeat the input name (attachment twice, or an attachment[] multi-file input) and every file under that name is attached to the same submission.
Turning uploads on for a form
In the dashboard: Form → Settings → Uploads. Toggle Allow file uploads, set a max size in MB and optionally restrict allowed types (file extensions like pdf, png, or MIME patterns like image/*). Leaving the type list empty allows any type that is not on the blocked list below.
The same setting is writable from the write API as part of a form update:
curl -X PATCH https://api.webforms.to/v1/forms/frm_xxx \
-H "Authorization: Bearer wf_live_your_key" \
-H "Content-Type: application/json" \
-d '{"uploads": {"allowFileUploads": true, "maxFileSizeMb": 10, "allowedFileTypes": ["pdf", "png", "jpg"]}}'Limits
- Free planFile uploads aren't available on Free at all - any file sent to a Free-plan form is rejected with "file uploads require a paid plan", even if the form's own toggle is on. Upgrade to Pro or Agency to accept files.
- Per-file sizeUp to 20MB on Pro, Agency and Enterprise. A form's own maxFileSizeMb setting is clamped to this ceiling on every submission, so a downgrade after the fact still enforces the new, lower limit.
- Files per submission10 files.
- Total attachment size per submission50MB, independent of the per-file limit - ten 20MB files would exceed it.
- Workspace storageCounted against your plan's total storage allowance. A file that would push the workspace over its quota is rejected even if it passes every other check.
Executable and script file types are always blocked regardless of your form's allow-list, because they are refused at upload time no matter what a form owner configures: exe, bat, cmd, msi, dll, sh, ps1, js, vbs, hta, docm/xlsm/pptm (macro-enabled Office formats) and similar. A double extension like invoice.pdf.exe is rejected on the real, final extension.
Partial acceptance
An oversized or disallowed file does not fail the whole submission - the text fields and any other, valid attachments are still stored, and the response lists what was rejected and why:
{
"ok": true,
"id": "sub_...",
"message": "Thanks! Your message was received.",
"files": [{ "name": "resume.pdf", "size": 214031 }],
"rejectedFiles": [{ "name": "photo.tiff", "reason": "not an accepted type" }]
}Reading attachments back
Attached files appear on the submission in the dashboard and in the Submissions API response under files, each with a signed, expiring URL - attachments are never public by default.
Get your endpoint
Free for 300 submissions a month. No card required.
Start free