File Uploads
Formoar supports file uploads on Starter, Pro, and Business plans. Users can attach files to their form submissions, and you'll receive them in your dashboard and email notifications.
File uploads are available on Starter plans and above. Submissions from free-plan forms that include files will be accepted, but the files will be silently stripped.
Adding file inputs to your form
To accept file uploads, add an <input type="file"> to your form and set the enctype attribute to multipart/form-data. This encoding type is required for file uploads — without it, browsers send only the filename instead of the file contents.
HTML form with file upload
<form
action="https://formoar.com/api/f/your-form-id"
method="POST"
enctype="multipart/form-data"
>
<label for="name">Name</label>
<input type="text" id="name" name="name" required />
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
<label for="resume">Upload your resume</label>
<input type="file" id="resume" name="resume" />
<button type="submit">Send</button>
</form>
Multiple files
You can accept multiple files in a single field by adding the multiple attribute. You can also use multiple separate file inputs with different name attributes.
Multiple file uploads
<!-- Multiple files in one input -->
<input type="file" name="attachments" multiple />
<!-- Or separate file inputs -->
<input type="file" name="resume" />
<input type="file" name="cover_letter" />
AJAX submissions with files
When submitting files via JavaScript, use FormData — not JSON. File uploads require multipart/form-data encoding, which FormData handles automatically.
JavaScript with file upload
const form = document.querySelector('form')
form.addEventListener('submit', async (e) => {
e.preventDefault()
const formData = new FormData(form)
const response = await fetch('https://formoar.com/api/f/your-form-id', {
method: 'POST',
body: formData,
// Do NOT set Content-Type — the browser sets it automatically
// with the correct multipart boundary
})
const result = await response.json()
if (result.ok) {
console.log('Files received:', result.files_received)
}
})
Do not set the Content-Type header manually when using FormData. The
browser must set it automatically to include the correct multipart boundary
string.
Plan limits
Each plan has different limits for file uploads:
| Plan | Max file size | Max files per submission |
|---|---|---|
| Free | Not available | Not available |
| Starter | 10 MB | 5 |
| Pro | 25 MB | 5 |
| Business | 50 MB | 5 |
If a file exceeds the size limit or the submission contains too many files, the entire submission is rejected with a 400 error.
Allowed file types
Formoar uses an allowlist of file extensions. Only the following file types are accepted:
Documents: pdf, doc, docx, txt, rtf, odt, csv, xls, xlsx
Images: jpg, jpeg, png, gif, webp, svg, heic, bmp, tiff
Archives: zip
Blocked file types
Executable and script file types are always blocked for security reasons:
exe, bat, cmd, msi, scr, vbs, js, ps1, sh, py, php, html, htm, dll, com, pif, wsf, wsh, cpl, reg, inf, lnk, jar, rb, pl
Files with double extensions (e.g., report.pdf.exe) are also rejected to prevent extension spoofing.
If you need support for a file type not on the allowlist, contact us and we'll consider adding it.
AJAX response fields
When files are included in a submission, the JSON response includes additional fields:
Success response with files
{
"ok": true,
"files_received": 2
}
If the form is on the free plan, files are silently stripped and the response indicates this:
Response when files are stripped (free plan)
{
"ok": true,
"files_skipped": true
}
Viewing uploaded files
Uploaded files appear in two places:
Dashboard
In the submission detail view, each uploaded file is listed with its original filename, file size, and a download link. Files are associated with the field name from your form (e.g., resume, attachments).
Email notifications
When email notifications are enabled, uploaded files are included as download links in the notification email. Each link is a signed URL that expires after 24 hours. To keep a permanent copy, download the files from the dashboard.
Storage and retention
Uploaded files are stored securely in Supabase Storage. Each file is placed in an isolated path based on the form ID and submission ID, preventing path traversal or conflicts between submissions.
Files follow the same retention policy as submission data:
| Plan | Retention |
|---|---|
| Starter | 90 days |
| Pro | 365 days |
| Business | Unlimited |
When a submission is deleted (either manually or by automatic retention cleanup), its associated files are also removed from storage.