Guides/API for forms with file uploads

API for forms with file uploads

Presigned URLs. Files never touch your server.

Updated March 2026

Need to accept file uploads? Resumes, documents, images? Sutrena does it with presigned URLs. You define a file field with accepted types and size limits. The client gets a presigned upload URL, uploads directly, then submits the form with a file reference. Files never pass through your server.

1. Create a form with a file field

Add a field with type "file". Specify accept for allowed types and maxFileSize in bytes. The client-intake template includes a file field by default.

curl -X POST https://sutrena.com/api/forms \
  -H "Authorization: Bearer st_trial_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Job Application",
    "fields": [
      { "name": "name", "label": "Full Name", "type": "text", "required": true },
      { "name": "email", "label": "Email", "type": "email", "required": true },
      { "name": "position", "label": "Position", "type": "select",
        "options": ["Engineering", "Design", "Marketing", "Sales"], "required": true },
      { "name": "resume", "label": "Resume", "type": "file",
        "accept": ".pdf,.doc,.docx", "maxFileSize": 10485760, "required": true },
      { "name": "cover_letter", "label": "Cover Letter", "type": "textarea" }
    ]
  }'

2. Request a presigned upload URL

Before submitting, request a presigned URL for each file field. Valid for 15 minutes. One PUT request allowed.

curl -X POST https://sutrena.com/api/forms/frm_xyz789/upload \
  -H "Content-Type: application/json" \
  -d '{
    "field": "resume",
    "filename": "jane-doe-resume.pdf",
    "contentType": "application/pdf"
  }'

# Response:
# {
#   "uploadUrl": "https://storage.sutrena.com/...",
#   "fileRef": "file_abc123",
#   "expiresAt": "2026-03-02T12:15:00Z"
# }

3. Upload the file and submit

PUT the file to the presigned URL. Then submit the form with the file reference instead of the actual file.

// 1. Upload file to presigned URL:
await fetch(uploadUrl, {
  method: "PUT",
  headers: { "Content-Type": "application/pdf" },
  body: fileBlob
});

// 2. Submit form with file reference:
await fetch("https://sutrena.com/api/forms/frm_xyz789/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Jane Doe",
    email: "[email protected]",
    position: "Engineering",
    resume: "file_abc123",
    cover_letter: "I am excited to apply for..."
  })
});

FAQ

What is the maximum file size?

You set it per field via maxFileSize (in bytes). Platform max is 10 MB (10485760 bytes) per file.

What file types are supported?

Whatever you put in the accept property. .pdf,.doc,.docx for documents, image/* for images, .csv,.xlsx for spreadsheets. You decide.

How long are uploaded files stored?

Same as submissions. Paid plans: indefinitely. Free plan: data persists as long as the account exists. Unclaimed trial accounts auto-delete after 24 hours.

Can I download uploaded files via API?

Yes. When you retrieve a submission, file fields include a download URL. Requires your API key.

What is Sutrena?

Sutrena is the web runtime for AI agents. Three primitives — pages, forms, and dashboards — accessible through one API. Your agent creates web artifacts, humans interact with them, and your agent gets the data back. Framework-agnostic. Works from any MCP client or HTTP client.

Get started in two API calls

1. Get a trial key (no auth, no signup)

curl -X POST https://sutrena.com/api/trial

2. Create a form + dashboard from a template

curl -X POST https://sutrena.com/api/forms \
  -H "Authorization: Bearer st_trial_xxx" \
  -H "Content-Type: application/json" \
  -d '{"templateId": "waitlist", "createDashboard": true}'

Ready to build?

Get a trial API key instantly with no signup, or create an account for the full experience.

API for forms with file uploads — Sutrena | Sutrena