Feature guide
File uploads
Accept file attachments (résumés, screenshots, documents) right on your form. Uploads are stored privately and surfaced as secure download links in your dashboard and email notifications. Available on paid plans.
enctype="multipart/form-data" on the <form>tag. Without it the browser sends only the file's name, not its contents.Add a file input
Add an <input type="file">and set the form encoding. That's the whole change. Everything else works like a normal submission.
<form action="https://shipmyform.com/f/frm_8Kx2mQ9pL4vN" method="POST" enctype="multipart/form-data">
<label>Name
<input type="text" name="name" required>
</label>
<label>Email
<input type="email" name="email" required>
</label>
<!-- The file input -->
<label>Résumé
<input type="file" name="resume">
</label>
<!-- Spam honeypot: keep it hidden and empty -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
<button type="submit">Apply</button>
</form>Accept several files
Add multipleto let one field take a few files, or use several file inputs, up to your plan's per-submission limit.
<label>Attachments
<input type="file" name="attachments" multiple>
</label>Submitting with JavaScript
If you post with fetch(), send a FormData body,notJSON. JSON can't carry files. Building the body straight from the form keeps the file parts intact.
const form = document.querySelector("form");
const res = await fetch(form.action, {
method: "POST",
body: new FormData(form), // includes the files
headers: { Accept: "application/json" },
});
const data = await res.json(); // { ok: true }The generators in our form generator already add the multipart encoding and a FormData submit when you include a file field.
Where the files go
Uploaded files are stored in private object storage, never on a public URL. In your dashboard, each file appears as a download link on the submission. Email notifications include a signed link that works without a login and expires after a few days. Every download is served as an attachment, so nothing can render or execute in the browser.
Limits by plan
| Plan | Per file | Per submission | Total storage |
|---|---|---|---|
| Free | — | — | No uploads |
| Starter | 10 MB | 5 files | 2 GB |
| Pro | 25 MB | 10 files | 25 GB |
Storage frees up as submissions age out under your retention policy. You can watch usage against your plan on the Usage page.
Error responses
If an upload is rejected, the response body includes an error code:
file_uploads_unavailable- The form is on the Free plan (or uploads aren't configured on the server). Upgrade to Starter or Pro to accept files.
file_too_large- One of the files is bigger than your plan's per-file limit.
too_many_files- The submission has more files than your plan allows.
too_large- The whole request exceeded the body size limit, usually several large files at once.