# Passing files (/files/passing-files)





Pass a file object to a compatible file input, or reference one of its properties when a block needs a specific value. Workflow file objects, API upload descriptors, and the API's run-file download records have different shapes.

## File objects [#file-objects]

Blocks that return platform files use a `UserFile` object. For example, a workspace file includes:

```json
{
  "id": "wf_V1StGXR8z5jdHi6BmyT7q",
  "name": "report.pdf",
  "url": "https://www.sim.ai/api/files/serve/ENCODED_STORAGE_KEY?context=workspace",
  "size": 245678,
  "type": "application/pdf",
  "key": "workspace/WORKSPACE_ID/FILE_STORAGE_KEY",
  "context": "workspace"
}
```

The IDs, key, and URL above illustrate the fields. Use the values Sim returns; do not construct them yourself.

| Field | Meaning |
| - | - |
| `id` | Opaque file identifier |
| `name` | Filename, including its extension |
| `url` | Access URL; authentication and lifetime depend on its source |
| `size` | Recorded file size in bytes |
| `type` | MIME type |
| `key` | Storage locator used by Sim; it is not a public access grant |
| `context` | Optional storage context, such as `workspace` or `execution` |
| `base64` | Optional encoded bytes; not included on every object |
| `version` | Optional content version for a workspace file |

The internal `key` and `context` fields may be omitted from output pickers and displayed logs. Their absence in a preview does not mean a file reference is unusable.

Generated documents can store generation source separately from the rendered download. Their recorded size or type can differ from the bytes a download returns.

**Read** returns file objects. **Get Content** returns extracted text in `contents`; **Fetch** returns file objects and `combinedContent`. For the operation settings, see [Using files in workflows](/files/using-in-workflows#the-file-block).

## Pass files between blocks [#passing-files-between-blocks]

Use the output picker or type `<` in a reference-capable input to select an earlier block's output. Keep the array index when selecting one file:

```text
<file.files>
<file.files[0]>
<gmail.attachments[0]>
<gmail.attachments[0].name>
<file.contents[0]>
```

Pass the full object to a file input when possible. The receiving block determines which formats, object or array inputs, and sizes it supports. Sim does not convert every file format for every block.

Use `.base64` only when the object includes it. JavaScript without imports can explicitly read bytes with `await sim.files.readBase64(file)` or text with `await sim.files.readText(file)` under the Function helper limits. In remote Function code, `<file.files[0].path>` requests a file mount; it is a special indexed reference, not a UserFile property. See [Function files](/workflows/blocks/function#files).

## Supply files to the API [#triggering-workflows-with-files]

Before calling the workflow, add a **Files** input named `document` to the entry trigger's input format and deploy that version. The UI uses the field type `file[]`; `files` remains a legacy compatibility alias. With a Start block named `Start`, the first processed file is available as `<start.document[0]>`.

Set `WORKFLOW_ID` and `SIM_API_KEY` in your shell. On self-hosted Sim, replace the Cloud origin with your deployment URL. Put workflow fields inside the v2 request's `input` object.

<Tabs items="['Base64', 'URL']">
  <Tab value="Base64">
    This example uploads a small text file containing `Hello, Sim.` followed by a newline. For another file, replace the encoded bytes, MIME type, and name together.

    ```bash
    curl --fail-with-body -X POST \
      "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \
      -H "X-API-Key: $SIM_API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{
        "input": {
          "document": [{
            "type": "file",
            "data": "data:text/plain;base64,SGVsbG8sIFNpbS4K",
            "name": "notes.txt",
            "mime": "text/plain"
          }]
        }
      }'
    ```
  </Tab>

  <Tab value="URL">
    Replace the example URL with a downloadable file URL that passes your deployment's network policy.

    ```bash
    curl --fail-with-body -X POST \
      "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/execute" \
      -H "X-API-Key: $SIM_API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{
        "input": {
          "document": [{
            "type": "url",
            "data": "https://example.com/report.pdf",
            "name": "report.pdf",
            "mime": "application/pdf"
          }]
        }
      }'
    ```
  </Tab>
</Tabs>

For a new file, `type` selects `file` or `url`; it is not the MIME type. `data` is a base64 data URL or a download URL, `name` is required, and `mime` is optional. The engine stores accepted new input files in execution storage and supplies an array of UserFile objects to the file-typed field before blocks run.

Authorized workspace-member callers can also supply an existing stored reference such as `{ "id": "CANONICAL_FILE_ID" }` or `{ "key": "STORAGE_KEY" }`. Public or system callers cannot use an arbitrary ID or key to read workspace files; their supplied stored references are limited to files already authorized for that execution. A caller-provided identifier does not grant access to neighboring files or another workspace.

## Download files from API responses [#receiving-files-in-api-responses]

Return the file object or saved file ID through a [Response](/workflows/blocks/response) block. A synchronous v2 response wraps the result in `data.output` and includes `data.runId`, `data.status`, and `data.error`. Check the run status even when the HTTP request succeeds.

For a completed run that returned an execution-produced file:

1. Set `RUN_ID` to the returned run ID.
2. Read the run with `includeOutput=true`.
3. Take the file's `id` or `downloadPath` from `data.files` and download it with the same authentication.

```bash
curl --fail-with-body \
  "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID?includeOutput=true" \
  -H "X-API-Key: $SIM_API_KEY"
```

Each projected entry in `data.files` has this shape:

```json
{
  "id": "file_123",
  "name": "output.png",
  "size": 34567,
  "type": "image/png",
  "downloadPath": "/api/v2/workflows/WORKFLOW_ID/runs/RUN_ID/files/file_123",
  "base64": null
}
```

Set `FILE_ID` to the returned file ID:

```bash
curl --fail-with-body \
  "https://www.sim.ai/api/v2/workflows/$WORKFLOW_ID/runs/$RUN_ID/files/$FILE_ID" \
  -H "X-API-Key: $SIM_API_KEY" \
  --output output.png
```

The ordinary `/api/files/serve/...` URL in a workflow file object requires a session and does not accept `X-API-Key`. Use the [run-file download endpoint](/api-reference/workflow-runs/downloadWorkflowRunFileV2) for execution artifacts. If you saved a workspace file with Write and returned its ID, use [Download file](/api-reference/files/downloadFile) at `/api/v2/files/{fileId}?workspaceId={workspaceId}`.

Execution files follow the run's retention lifecycle and may later return `404`. Save them to Files when later runs need a workspace resource. Returning a pointer or downloading it does not make a public share link.

To inline eligible output bytes, request `includeFileBase64: true`. The execute request's `base64MaxBytes` can lower the 16 MiB total inline ceiling; it cannot raise it. Async execution rejects these options. On a run read, base64 requires `includeOutput=true` and has a per-file ceiling; an oversized file can return `413` with its download path. Use authenticated downloads for large outputs. See [Execute workflow](/api-reference/workflows/executeWorkflowV2) and [Get workflow run](/api-reference/workflow-runs/getWorkflowRunV2) for the full option contracts.

## File limits [#file-limits]

There is no single limit for every upload or read path. Storage quota, parser limits, sandbox budgets, and the receiving provider's limits apply independently.

| Path | Current hard limit |
| - | - |
| Workspace direct upload | 5 GiB per file, subject to workspace storage quota |
| Legacy buffered workspace upload | 100 MiB per file |
| New base64 or URL input processed for a workflow file field | 20 MiB per file |
| File Fetch | 100 MiB download; 30-second download timeout |
| File Get Content | 64 MiB source per file and 64 MiB combined extracted text |
| File Write text or existing-file input | 50 MiB per file |
| Function buffered mounts | 10 MiB per file; 50 MiB total |
| Function URL mounts | 500 MiB per file; 2 GiB total |
| Function automatic exports | 20 files; 50 MiB total |

Workspace uploads use upload sessions for large transfers; API callers should follow the [file upload API](/api-reference/files/createFileUpload) rather than assume a multipart JSON or buffered upload shares the 5 GiB ceiling. A large stored file can still exceed a parser, model, or third-party upload limit. See [Function](/workflows/blocks/function) and the receiving block's reference before processing it.

## Blocks that work with files [#blocks-that-work-with-files]

| Task | Examples |
| - | - |
| Read or extract content | [File](/integrations/file), [Agent](/workflows/blocks/agent), [Mistral Parser](/integrations/mistral_parse) |
| Analyze an image or transcribe audio | Vision, STT |
| Receive or send attachments | [Gmail](/integrations/gmail), [Slack](/integrations/slack) |
| Generate media | TTS, Image Generator, Video Generator |
| Store files externally | [Supabase](/integrations/supabase), [S3](/integrations/s3), [Google Drive](/integrations/google_drive), [Dropbox](/integrations/dropbox) |

These integrations support particular file operations; check their format and authentication requirements. Agent attachment support depends on the selected model and provider.
