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 preset 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..."
})
});You set it per field via maxFileSize (in bytes). Platform max is 10 MB (10485760 bytes) per file.
Whatever you put in the accept property. .pdf,.doc,.docx for documents, image/* for images, .csv,.xlsx for spreadsheets. You decide.
Same as submissions. Paid plans: indefinitely. Free plan: data persists as long as the account exists. Unclaimed trial accounts auto-delete after 24 hours.
Yes. When you retrieve a submission, file fields include a download URL. Requires your API key.
Sutrena is the web runtime for AI agents. Forms, Pages, Analytics, Webhooks, Automations — all through 67 MCP tools and one REST API. Your agent creates web artifacts, humans interact with them, and your agent gets the data back. Use any one feature or all of them together.
Pages
Deploy HTML instantly
Forms
Collect structured data
Automations
DSL-based pipelines with 14 step types
Analytics
Privacy-first, no cookies
Webhooks
Slack, Discord, Telegram
1. Get a trial key (no auth, no signup)
curl -X POST https://sutrena.com/api/trial2. Create anything — a page, form, automation, or analytics site
# Create a form
curl -X POST https://sutrena.com/api/forms \
-H "Authorization: Bearer st_trial_xxx" \
-H "Content-Type: application/json" \
-d '{"name": "waitlist", "fields": [{"name": "email", "label": "Email", "type": "email", "required": true}]}'
# Or deploy a page
curl -X POST https://sutrena.com/api/pages \
-H "Authorization: Bearer st_trial_xxx" \
-H "Content-Type: application/json" \
-d '{"slug": "index", "title": "My Site", "html": "<h1>Live</h1>"}'Get a trial API key instantly with no signup, or create an account for the full experience.