Skip to main content

Documentation

File Uploads

File uploads use a session-based flow: create a session, upload files to it, then submit your form with the session token. Uploads are linked to the submission automatically.

How it works

  1. Enable file uploads in your form's settings and configure allowed types and limits
  2. Create an upload session by POSTing to /f/YOUR_FORM_ID/sessions
  3. Upload files to the session one at a time
  4. Submit your form with the _session field to link uploads to the submission

1. Create a session

Sessions are valid for 1 hour. You must create one before uploading any files.

POST /f/YOUR_FORM_ID/sessions

// Response (201)
{
 "session_id": "base64-encoded-token"
}

2. Upload files

Upload each file as multipart form data. Include the session token from the previous step.

POST /f/YOUR_FORM_ID/upload
Content-Type: multipart/form-data

Fields:
 session_id: "token-from-step-1"
 file: (binary)

// Response (201)
{
 "id": "file-uuid",
 "filename": "photo.jpg",
 "content_type": "image/jpeg",
 "size": 12345,
 "url": "/uploads/...?token=..."
}

3. Submit with session

Include the _session field alongside your normal form fields. Uploaded files are automatically attached to the submission.

POST /f/YOUR_FORM_ID
Content-Type: application/json

{
 "name": "Jane",
 "email": "[email protected]",
 "_session": "token-from-step-1"
}

The _session field is a reserved field — it's extracted automatically and won't appear in your submission data.

JavaScript example

// 1. Create session
const sess = await fetch("/f/YOUR_FORM_ID/sessions", { method: "POST" });
const { session_id } = await sess.json();

// 2. Upload a file
const form = new FormData();
form.append("session_id", session_id);
form.append("file", fileInput.files[0]);
await fetch("/f/YOUR_FORM_ID/upload", { method: "POST", body: form });

// 3. Submit with session
await fetch("/f/YOUR_FORM_ID", {
 method: "POST",
 headers: { "Content-Type": "application/json" },
 body: JSON.stringify({
 name: "Jane",
 email: "[email protected]",
 _session: session_id,
 }),
});

Defaults & limits

Setting Default
Max file size 20 MB
Max files per submission 5 (up to 20)
Allowed types JPEG, PNG, GIF, PDF
Session lifetime 1 hour
File URL validity 90 days

All settings are configurable per form. Allowed types also support WebP, WebM, and Office formats (DOCX, XLSX, PPTX). Files are validated against their content using magic bytes — renaming a file won't bypass type checks.

Uploaded files are not private

File URLs are token-signed but anyone with the URL can access the file. Do not use file uploads to collect sensitive documents such as government IDs, medical records, or financial statements.

Error responses

Status Meaning
403 Uploads disabled, form disabled, or domain not allowed
422 Invalid/expired session, file too large, type not allowed, or too many files
429 Rate limited or storage limit reached