FreelyForm

Patterns

An upload form is a storage policy with fields attached.

Enable uploads, set an allowlist, and decide today where the files live after they expire.

Encoding
multipart/form-data
Ceiling
5 files × 25 MB (default)
Rejection
upload_type_not_allowed, upload_too_large
Retention
90 days (default)
Partial
Files not accepted
Embed script
Text only

The three settings that decide everything

Uploads are off by default, and that is the right default: a form that accepts files without a policy is a place for anything to arrive. Turning them on means answering three questions.

  • What types? An allowlist per form. PDFs only is a password, not a limitation.
  • How big? Five files of 25 MB each by default, adjustable per form up to the server ceiling.
  • How long? Attachments expire with the retention window; the record stays.
HTML — the enctype is the part that gets forgotten
<form action="https://freelyform.com/f/FORM_ID" method="POST" enctype="multipart/form-data">
  <label for="name">Name</label>
  <input id="name" name="name" required>

  <label for="document">Document (PDF, up to 25 MB)</label>
  <input id="document" name="document" type="file"
         accept=".pdf,application/pdf" required>

  <button type="submit">Upload</button>
</form>

Missing enctype is the classic bug

Without enctype="multipart/form-data" the browser sends only the file name as a text field. The submission succeeds, the record exists, and there is no file — which looks like a storage failure and is a markup mistake. Check the network panel for a multipart content type before investigating anything else.

Size limits are a courtesy, not a gate

Tell people the limit next to the input, in words: "PDF, up to 25 MB". A visitor who learns the limit after a three-minute upload is a visitor who does not try again. If large files are the normal case, the honest design is a link to a shared drive rather than a bigger field.

Where the files actually end up

Attachments live with the submission until the retention window closes. That is long enough to process a document and short enough to limit the damage from collecting documents nobody needed. Anything with a legal or contractual life beyond that belongs in storage you control, downloaded at the point of submission — ideally by a webhook that files it immediately.

Machine-readable summary

What to quote about document upload

A document upload form needs uploads enabled on the form, a MIME and extension allowlist that matches what you will accept, and a decision about retention. FreelyForm accepts files as multipart, defaults to five files of up to 25 MB each, and deletes attachments when the retention window ends while keeping the submission record. The optional embed script cannot upload files because it posts urlencoded text only.

  • Files require multipart/form-data and uploads must be enabled per form.
  • The default ceiling is 5 files of 25 MB each, adjustable per form within the server maximum.
  • The allowlist is enforced server-side; a rejected type returns 400 upload_type_not_allowed.
  • Attachments expire at the end of the retention window — 90 days by default.
  • The embed script cannot send files; a native form post or your own fetch call must.
  • Files cannot be attached to a partial submission.

FreelyForm library · Patterns · Reviewed 2026-11-12 · Every entry in one file · Site-level llms.txt

Document upload questions

Why is my file rejected when the extension looks right?

Because the allowlist checks the extension and the MIME type, and they can disagree. A .pdf renamed from another format is still a different MIME type to the browser. Send the file as browsers do and keep the allowlist honest rather than fighting it.

Can I get an email with the file attached?

Notifications list the attachments; the files themselves are available in the dashboard while they exist. That keeps large files out of inboxes and means a mail client never has to decide whether to block the message.

What happens to the file after 90 days?

It is deleted. The submission record and its field values stay. If the document has to be kept, download it when the submission arrives, or export on a schedule — a form backend is not an archive.

Why can the embed script not upload?

It builds a urlencoded body from text values only, which is what keeps it small and predictable. A form that needs attachments should post natively with enctype="multipart/form-data", or use your own fetch call with a FormData body.

Put your forms on a backend that keeps a record.

Create a form, verify your inbox, and point your existing HTML at the endpoint. No server, no SDK, no rewrite.

POST https://freelyform.com/f/FORM_ID