Skip to main content
SLang represents uploaded and stored files with the FILE type. A FILE value carries file metadata and can be streamed, stored, downloaded, or passed to modules such as AI.prompt.

Upload and Store a File

HTTP file uploads are exposed through @request.files.<fieldName>. Use store fileValue to persist the upload to Sutro object storage before saving it on an entity.
import "AI"

entity User
  subject
  identity email
  fields
    email: EMAIL
    displayName: TEXT?

entity Document
  fields
    title: TEXT
    file: FILE
    summary: TEXT?

relation User[documents] 1 --- 0..* Document[owner]

action UploadDocument(title: TEXT, file: FILE): Document
  body
    user := @subject.entity
    storedFile := store file
    document := create Document {
      owner := user
      title := title
      file := storedFile
    }
    return document

action SummarizeDocument(documentId: TEXT): Document
  body
    user := @subject.entity
    document := single Document where @id == documentId and owner == user
    summary := AI.prompt(
      message := "Summarize the uploaded document.",
      attachments := [document.file],
      provider := "openai",
      maxTokens := 600
    )
    update document {
      summary := summary
    }
    return document

trigger UploadDocument on HttpRequest
  endpoint POST /documents
  arguments
    title := @request.body.title
    file := @request.files.file
  auth
    @subject is @defined

trigger SummarizeDocument on HttpRequest
  endpoint POST /documents/{documentId}/summary
  arguments
    documentId := @request.path.documentId
  auth
    @subject is @defined
Clients should send upload requests as multipart/form-data with a file field matching the trigger binding. In the example above, the field name is file.

What store Returns

store accepts a FILE and returns a persisted FILE. The stored value keeps the original file name, MIME type, size, and a Sutro storage location. Persisted FILE values can be saved on entities and later used in actions. Use store when the file must survive after the current request. If an action only needs to process the upload immediately, it can pass the request file directly to another function or module without storing it first. Uploaded or stored FILE values can also be used as top-level request bodies with HTTP.fetch for outbound raw binary uploads. HTTP.fetch sends the file bytes unchanged and uses the file MIME type as the request content-type unless you provide one explicitly. HTTP.fetch can also return downloaded bytes as a FILE when you pass responseType := "file". Store the returned file before saving it on an entity if it must survive after the current action.

File Fields

Use FILE fields for documents, images, PDFs, CSVs, or any uploaded blob that should be attached to an entity. FILE values are especially useful with:
  • Document upload workflows.
  • AI prompts with attachments := [document.file].
  • Audit records that need to retain source files.
  • Imported data pipelines where a queue processes an uploaded file later.

Upload Limits

Generated app HTTP routes accept multipart uploads for trigger arguments bound from @request.files. The local and generated runtimes enforce upload limits before the SLang action runs, so oversized uploads fail at the HTTP layer.