To upload files from a plain HTML form without a server, add enctype="multipart/form-data" and a file input, and set the form's action to a FormSubmit endpoint. FormSubmit stores each file privately, links it in your notification email and dashboard, and passes signed links to your integrations.
Basic upload form
<form action="https://formsubmit.app/f/YOUR_FORM_ID" method="POST" enctype="multipart/form-data" class="fs-form">
<div class="fs-field">
<label for="fs-name" class="fs-label">Name</label>
<input id="fs-name" type="text" name="name" required class="fs-input">
</div>
<div class="fs-field">
<label for="fs-email" class="fs-label">Email</label>
<input id="fs-email" type="email" name="email" required class="fs-input">
</div>
<div class="fs-field">
<label for="fs-files" class="fs-label">Files</label>
<input id="fs-files" type="file" name="files" multiple required class="fs-input">
</div>
<div class="fs-field">
<label for="fs-note" class="fs-label">Note</label>
<textarea id="fs-note" name="note" rows="5" class="fs-input"></textarea>
</div>
<!-- Honeypot: leave this hidden field empty to catch bots -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="display:none">
<!-- Optional: where to send people after submitting -->
<!-- <input type="hidden" name="_redirect" value="https://yoursite.com/thanks"> -->
<button type="submit" class="fs-button">Send</button>
</form>
<style>
.fs-form { max-width: 32rem; margin: 0 auto; display: grid; gap: 1.1rem; font-family: system-ui, sans-serif; }
.fs-field { display: grid; gap: 0.35rem; border: 0; padding: 0; margin: 0; }
.fs-label { font-size: 0.875rem; font-weight: 600; color: #18181b; }
.fs-input { width: 100%; box-sizing: border-box; border: 1px solid #d4d4d8; border-radius: 0.5rem; padding: 0.6rem 0.75rem; font: inherit; font-size: 0.9rem; }
.fs-input:focus { outline: 2px solid #6366f155; border-color: #6366f1; }
.fs-choice { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; }
.fs-help { font-size: 0.75rem; color: #71717a; margin: 0; }
.fs-button { background: #18181b; color: #fff; border: 0; border-radius: 0.5rem; padding: 0.7rem 1rem; font-weight: 600; cursor: pointer; }
.fs-button:hover { background: #27272a; }
</style>Key details:
enctype="multipart/form-data"is required — without it the browser only sends the file name.- Each file input needs a
name. Addmultipleto accept several files in one input. accept=".pdf,image/*"filters the file picker (it's a hint, not a security control).
Limits
| Plan | Per file | Total storage |
|---|---|---|
| Free | 10 MB | 100 MB |
| Starter | 10 MB | 250 MB |
| Pro | 10 MB | 1 GB |
| Business | 25 MB | 10 GB |
Plain multipart submissions are capped at about 4.5 MB per request by our serverless infrastructure. For larger files, upload directly from the browser to storage and send a reference — see direct uploads.
A job application form
The job application template is a good starting point: name, email, phone, LinkedIn, position, resume upload and cover letter.
Where do the files go?
- Your notification email lists each attachment as a link.
- In the dashboard, open a submission to preview images and PDFs or download any file.
- Webhooks, Slack, Discord, Airtable and Google Sheets receive signed links.
Files are private, count toward your storage quota, and are deleted with their submission (manually or via retention).