Skip to main content
Workflows can declare parameters of type: file. To submit a task against one, upload the file first, then pass the returned file_key as the parameter value. The path runs through S3 with a presigned PUT — uploads don’t touch the API server’s bandwidth.

The flow

Three calls in order:
  1. POST /api/v1/r/files/presign — describe the file. Returns file_key, upload_url, and upload_headers.
  2. PUT <upload_url> — upload the file body directly to S3, sending every header in upload_headers verbatim.
  3. POST /api/v1/r/workflows/{workflowId}/run (or /r/workflows/slug/{workflowSlug}/run) with the file_key as the value for the file parameter.

Request a presigned URL

Response:

Upload to S3

Send the file body as the PUT request body with all of upload_headers attached. The signature enforces them — if you skip Content-Length or If-None-Match, S3 returns 403. If a file already exists at the key, S3 returns 412 (overwrite prevented).
The Content-Length value must match the file_size you sent at step 1 exactly.

Submit the workflow

Pass file_key as the parameter value:
The agent fetches the file from S3 when the task runs.

End-to-end examples

Retention and limits

  • Input files uploaded via /r/files/presign are kept for 1 day then removed by S3 lifecycle policy. Submit the task within that window.
  • Task outputs are retained for 7 days. After that the download_url you receive from GET /r/tasks/{taskId}/result stops working.
  • Default per-file size limit is 500 MB. Larger limits are a deployment configuration. For files near or above this limit use the multipart upload endpoints (/uploads/multipart/...) instead — they presign each part separately.

Multipart for large files

For files that exceed the single-part limit, use the multipart flow:
  1. POST /api/v1/uploads/multipart/initiate — start an upload, get an upload ID.
  2. POST /api/v1/uploads/multipart/presign-parts — request signed URLs for each part.
  3. PUT each part to its signed URL.
  4. POST /api/v1/uploads/multipart/complete — finalize, get the same file_key shape back.
The single-part flow is simpler — use multipart only when you need it. The multipart endpoints (initiate, presign-parts, complete) accept a user session token only — they reject sk- integration credentials and dk- device credentials with 401. Single-part /r/files/presign accepts all three. If you call the API with an sk- or dk- credential, use the single-part presign flow.