FormThunder isn't open yet. This site describes the service as it will run at launch. Find out more

FormThunder
Menu

Forms, updated

Attachments and uploader

FormThunder accepts files in two ways, both on Pro and Agency, and only on forms with attachments turned on. A direct multipart upload handles files up to 5 MB each, in a request up to 6 MB. The advanced uploader sends files to storage first, which allows up to 25 MB per file. Files are attached to the email and linked from the dashboard.

Turn attachments on

Set attachments_enabled on the form in the dashboard, or through your AI, the CLI or the API. Otherwise, files are ignored and the response carries a warning. The rest of the submission still arrives.

Direct upload

html
<form action="https://formthunder.com/submit" method="POST" enctype="multipart/form-data">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY">
  <input type="email" name="email" required>
  <input type="file" name="attachment" required>
  <button type="submit">Send</button>
</form>

With fetch, pass a FormData object and leave out the Content-Type header, so the browser can set the boundary.

js
await fetch("https://formthunder.com/submit", { method: "POST", body: new FormData(form) });

Advanced uploader

The helper script turns a file input into a multi-file uploader.

html
<input type="file" name="attachment"
  data-advanced="true"
  data-max-files="5"
  data-max-file-size="25mb"
  accept=".pdf,.png,.jpg">

<script src="https://formthunder.com/client/script.js" async></script>
AttributeWhat it does
data-advancedSet to true to turn the input into the uploader.
data-form-idThe form's key. It's read from the form's access_key if you leave it out.
data-max-filesHow many files. Defaults to 1.
data-max-file-sizeSize per file, such as 25mb. The limit is 25 MB.
data-contentText shown in the drop area.
acceptFile types offered in the picker.

Uploading from your own code

Ask for a signed URL, PUT the file there, then submit its ID in the attachment field.

js
const sign = await fetch("https://formthunder.com/api/uploads/sign", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ access_key: key, filename: file.name, size: file.size, type: file.type }),
}).then((r) => r.json());

await fetch(sign.url, { method: sign.method, headers: sign.headers, body: file });

await fetch("https://formthunder.com/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ access_key: key, email, attachment: [sign.upload_id] }),
});

How files reach you

Files are attached to the notification email up to a total size. Past that, the email links to them instead. Webhook payloads list each file's name, size, type and a download URL.

Treat files from a public form with the same care as any email attachment.