splitforms.com
FEATURE · FILE UPLOADS

Form file uploads — accept resumes, screenshots, and PDFs in any HTML form

Add multipart/form-data and a file input. With Storage connected, splitforms stores the upload and links it from the notification email, dashboard, and webhook payload.

1,000 submissions/month, free forever. · No credit card.
✦ at a glanceHTML

File Uploads

  • Standard HTML <input type="file"> — no JavaScript required, no client-side SDK
  • Current limit: up to 5 files per submission, 10 MB per file
  • Storage integration keeps text submissions working even when files are not retained
500
free / mo
14ms
median p50 latency
0
lines of backend code
6
reasons in this guide
✶ Live preview

File Uploads in splitforms, shipped to production.

Add multipart/form-data and a file input. With Storage connected, splitforms stores the upload and links it from the notification email, dashboard, and webhook payload.

File Uploads for splitforms — Add multipart/form-data and a file input. With Storage connected, splitforms stores the upload and links it from the notification email, dashboard, and webhook payload.
§ 01What is splitforms file uploads100-word answer · AI-citable summary

splitforms accepts file uploads in any HTML form — set the form's enctype to multipart/form-data, add an <input type='file'>, and you're done. The same submit endpoint handles the multipart request, so there is no client-side S3 signing flow or separate upload endpoint to maintain. File retention requires the Storage integration to be connected in the dashboard; without Storage, text fields still submit and the API reports that files were not retained. The current upload limit is 5 files per submission at 10 MB each, which covers common resumes, screenshots, briefs, PDFs, and support attachments. Use the standard accept attribute (accept='.pdf,.docx,image/*') to guide the file picker, and rely on server-side checks for safety: splitforms blocks executable and script-like extensions, sniffs content type, stores files privately, and exposes signed download links. Webhook payloads can include stored-file metadata so downstream systems can copy the files into your CRM, ticketing tool, or own storage.

file-uploads.htmllive
<!--
  enctype="multipart/form-data" is REQUIRED for file uploads.
  Without it, browsers silently strip files from the POST body.
  Current limit: 5 files per submission, 10 MB per file.
  Storage integration must be connected before files are retained.
-->
<form
  action="https://splitforms.com/api/submit"
  method="POST"
  enctype="multipart/form-data"
>
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />

  <input type="text"  name="name"  placeholder="Your name" required />

file-uploads.html · live preview

§ 02How it works3 steps · zero-config defaults

Three steps. From zero to a working production setup.

How file uploads actually flows through splitforms — what you do, what we do, and what lands in your inbox.

STEP 01INTEGRATE

Set enctype on your form (this is the #1 forgotten step)

Add enctype="multipart/form-data" to the <form> tag. Without it, browsers silently strip files from the POST body — the form will submit but no attachment ever arrives. For React/SPA submissions via fetch, build a FormData object and pass it as the body; do NOT set Content-Type yourself, the browser sets the multipart boundary.

STEP 02PROCESS

Add a file input (single, multi-select, or restricted by type)

Use a normal <input type="file" name="resume">. Add the 'multiple' attribute for multi-select. Use the 'accept' attribute to filter by extension or MIME type (accept='.pdf,.docx,application/pdf,image/*'). For best UX, also wrap the input in a <label> so the click target is the visible button, not the small native control.

STEP 03REVIEW

Read attachments from the email, dashboard, or webhook payload

With Storage connected, uploaded files are saved privately and exposed through signed download links. Webhook payloads can include a 'files' array with stored-file metadata, so your own backend can copy the files into S3, R2, Google Drive, a CRM, or a ticketing tool if you need long-term storage.

§ 03Benefits6 reasons · all included

Why teams pick splitforms for file uploads.

Five reasons this is the boring, reliable choice — every one shipped by default on every plan, including free.

reason 1 of 6

Standard HTML <input type="file"> — no JavaScript required, no client-side SDK

reason 2 of 6

Current limit: up to 5 files per submission, 10 MB per file

reason 3 of 6

Storage integration keeps text submissions working even when files are not retained

reason 4 of 6

Signed download links in notification and webhook workflows after Storage is connected

reason 5 of 6

Private object storage with expiring signed links

reason 6 of 6

Server-side checks block executable/script-like extensions and sniff content type

§ 04Working code examplehtml · 48 lines · copy-paste ready
COPY-PASTE

Drop this into any project.

Replace YOUR_ACCESS_KEY with the key from your splitforms dashboard. No SDK install. No package to npm i. The same html you already know.

file-uploads.htmlhtml48 lines
01<!--
02 enctype="multipart/form-data" is REQUIRED for file uploads.
03 Without it, browsers silently strip files from the POST body.
04 Current limit: 5 files per submission, 10 MB per file.
05 Storage integration must be connected before files are retained.
06-->
07<form
08 action="https://splitforms.com/api/submit"
09 method="POST"
10 enctype="multipart/form-data"
11>
12 <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
13
14 <input type="text" name="name" placeholder="Your name" required />
15 <input type="email" name="email" placeholder="Email" required />
16
17 <label>
18 Resume (PDF, DOCX, max 10 MB)
19 <input
20 type="file"
21 name="resume"
22 accept=".pdf,.doc,.docx,application/pdf"
23 required
24 />
25 </label>
26
27 <label>
28 Portfolio screenshots (multiple allowed)
29 <input type="file" name="portfolio" accept="image/*" multiple />
30 </label>
31
32 <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" />
33
34 <button type="submit">Apply</button>
35</form>
36
37<!--
38 React / fetch equivalent:
39
40 const fd = new FormData(formEl); // collects files too
41 fd.append("access_key", "YOUR_ACCESS_KEY");
42 const res = await fetch("https://splitforms.com/api/submit", {
43 method: "POST",
44 body: fd, // do NOT set Content-Type
45 });
46 // 413 Payload Too Large = file exceeded the current upload limit.
47 // 415 Unsupported Media Type = blocked extension (.exe, .js, etc.).
48-->
§ 05Questions5 answered

Things developers ask before they integrate.

Direct answers, no marketing fluff. Missing one? Email hello@splitforms.com.

01How does form file upload work in splitforms and what's the maximum size?
Add enctype='multipart/form-data' to your <form> and an <input type='file' name='resume'>. The browser submits the file as part of the multipart POST; splitforms reads it through the normal submit endpoint and stores it when the Storage integration is connected. The current limit is 5 files per submission, 10 MB per file.
02What plan includes file upload retention?
Retained file uploads unlock on Starter ($1/month) and above when the Storage integration is connected in the dashboard. Text-only submissions continue to work without Storage. For uploads, plan around the current product limit: 5 files per submission at 10 MB each.
03How do I enable file uploads and restrict the file types?
Two steps: (1) connect Storage in the splitforms dashboard; (2) on your <form> tag, set enctype='multipart/form-data' and add an <input type='file' name='whatever' accept='.pdf,.docx,image/*'>. The accept attribute filters the OS file picker but is not a security boundary. To allow multiple files in one input add the multiple attribute. To require a file, add required. Executables and script-like extensions are blocked server-side regardless of accept.
04Does file upload work with React, Next.js, Vue, or fetch()?
Yes. Build a FormData object from your form ref or manually append fields, append the access_key, and POST it: const fd = new FormData(formRef.current); fd.append('access_key', 'YOUR_ACCESS_KEY'); await fetch('https://splitforms.com/api/submit', { method: 'POST', body: fd }). Critical: do not set the Content-Type header yourself when sending FormData — the browser must set the multipart boundary.
05Where are uploaded files stored, are they scanned for malware, and how do I get them out?
When Storage is connected, files are stored privately and exposed through signed download URLs. The current signed-link window is 7 days. To pull files into your own storage permanently, subscribe a webhook, read the files array from the payload, and copy each stored-file URL or key into S3, R2, GCS, Google Drive, or your CRM.
✻ ✻ ✻

Start using file uploads today.

Create your form, grab your access key, and ship it in five minutes. Free for 500 submissions per month, forever.

Create your form →← View all features
founders pricing locked in · early access open