Document Upload
Bring files into a workflow and store them where they need to go.
Document Upload ingests files and stores them — from a customer uploading a form, from a web link your workflow picks up, or from content a previous skill produced. It is the entry point for anything file-shaped, and the documentId it returns is what every downstream document skill works from.
How it works
Input resolution — resolves input from
$input(the previous skill's output) or$secret(vault secrets).Validation — checks the configuration and the source/destination combination.
Source handling — when
source='remoteUrl', streams and downloads the file.Destination routing:
conversation— stores in the in-memory cache, returns adocumentId.storage— writes to the specified path, returns astoragePath.signedUrl— performs an HTTP PUT/POST to the URL you provide.
Output envelope — builds a uniform output envelope.
Execution — blocking. The skill returns only after the upload completes or fails.
Worked example: collecting loan applications
A financial institution automates the first step of a loan application: collecting the form and its supporting documents — ID proof, income statements — directly from the customer.
The problem. Collecting and organizing documents from many applicants by hand is slow, error-prone, and creates delays. You need a secure, automated way for customers to submit files straight into the workflow.
The approach. Start the workflow with a Document Upload skill. Files are ingested and stored automatically, ready for the agent to process.
Configure it to collect a PDF application and save it to persistent storage:
Set the source. Under Source, select User Input — a person will be uploading the file.
Constrain and explain. In Supported File Types, enter the allowed extensions (
pdf). In Display Message, write the instruction the customer will see: "Please upload your completed Loan Application Form (PDF)."Choose the destination. Select Storage to save the document permanently. Optionally set a Storage Path (
new-applications/customer-xyz/) to organize documents into subfolders.

The documentId this returns is what you pass to Document Fetch, Document To Image, or Document Delete later in the workflow.
Configuration reference
destination
'conversation' | 'storage' | 'signedUrl'
✅
Final storage target.
source
'userInput' | 'content' | 'remoteUrl'
✅
How the file is supplied.
fileBase64
string
when source='content'
Base-64 encoded content.
remoteUrl
string
when source='remoteUrl'
Pre-signed or public GET URL.
remoteUrlHeaders
object
—
Extra headers for the remote GET.
supportedFileTypes
array
— (source='userInput')
Allowed extensions, e.g. ["pdf"].
displayMessage
string
— (source='userInput')
UI hint shown to the user.
storagePath
string
— (destination='storage')
Folder/key prefix in the bucket.
documentId
string
—
Force object key / overwrite.
signedUrl
string
when destination='signedUrl'
Pre-signed PUT/POST URL.
signedUrlMethod
'PUT' | 'POST'
— (destination='signedUrl')
Defaults to PUT.
signedUrlHeaders
object
—
Extra headers for the push.
name
string
—
Display label on the canvas.
description
string
—
Long-form help text.
Output
statusCode
number
✅
200 success · 400 bad request · 500 internal error.
documentId
string | null
✅
Identifier for downstream skills. null when destination='signedUrl'.
mimeType
string
✅
Detected MIME type, e.g. application/pdf. Useful for conditional branching.
error
string | null
—
Error message if processing failed; null on success.
Errors
All errors populate error and set success=false.
VALIDATION_ERROR
Invalid field combination or a missing required field.
DOWNLOAD_FAILED
source='remoteUrl' and the HTTP GET failed.
UPLOAD_FAILED
Writing to storage or the signed URL failed.
UNSUPPORTED_TYPE
The user selected a file type not in supportedFileTypes.
Security
Use
$secretfor tokens inremoteUrlHeadersorsignedUrlHeaders— they are redacted from logs.Files in
conversationscope follow the chat-retention TTL and are encrypted.Persistent storage inherits bucket IAM from
storageId.Signed-URL pushes never log the full URL, so write permissions cannot leak.
Testing in isolation
To execute this skill alone — via the UI Test button or directly:
Path —
/skill-runtime/workflows/nodes/DocumentUpload/executeMethod —
POSTBody:

To add this skill to an agent, see Adding a Skill to the Agent.
Last updated

