---
id: file--distribute-files
title: "Distribute files"
summary: "Uploads files from a local folder of the environment data folder to a remote server over FTP, FTPS or SFTP. Either scans the whole local file group (e.g. on a Timer) or uploads the single file it receives as `ViaFileInfo`. Optionally deletes or moves the local file afterwards. The counterpart of **Collect files**."
audience: user
keywords: "input, continue, transferprotocol, remotehost, port, username, password, clientcredentials, remotepath, createremotepath, localfilegroup, filenamepattern, olderthanhours, orderby, tempnametemplate, existingremotefile, postprocessing, postprocessfilegroup, paralleluploadcount, logfileinfo"
---
# Distribute files

Uploads files from a local folder of the environment data folder to a remote server over FTP, FTPS or SFTP. Either scans the whole local file group (e.g. on a Timer) or uploads the single file it receives as `ViaFileInfo`. Optionally deletes or moves the local file afterwards. The counterpart of **Collect files**.

## Pins

| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | `NoInputData`, `Viaducta.TypeSystem.Metadata.ViaFileInfo` | `NoInputData` (e.g. Timer): uploads every matching file of `LocalFileGroup`. `ViaFileInfo` (e.g. from Collect files): uploads only the file at `FilePath`. |
| Continue | continue | `NoInputData` | Called once after the upload finished, also when no file matched. Always sends `NoInputData`, also when the input was a `ViaFileInfo`. |

## Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `TransferProtocol` | dropdown: `1` FTP, `2` SFTP, `3` FTPS | `2` | Protocol. |
| `RemoteHost` | string | `localhost` | Required. Host name or IP of the server. |
| `Port` | integer | `0` | `0` = default port (21 for FTP/FTPS, 22 for SFTP). |
| `UserName` | string (max 256) | | Login user. |
| `Password` | password (max 256) | | Login password. For SFTP password authentication is used only when set. |
| `ClientCredentials` | string | | Optional files on the Viaducta server, separated by `;`. SFTP: private key files (without passphrase). FTP/FTPS: client certificate files. |
| `RemotePath` | string | | Remote directory to upload to, e.g. `/incoming/orders`. For FTP/FTPS it must start with `/` (empty = `/`). For SFTP empty = login directory. |
| `CreateRemotePath` | boolean | `false` | Create `RemotePath` (including parent folders) when it doesn't exist. |
| `LocalFileGroup` | folder (FolderExplorer) | | Required. Local folder relative to the environment data folder, e.g. `/outbound/orders`. Created if missing. |
| `FileNamePattern` | string | `*` | File name mask with `*` and `?` wildcards (`*.csv`, `ORD_*.xml`). Only used when scanning. |
| `OlderThanHours` | integer | `0` | Scan only files not modified for at least this many hours. `0` = all files. |
| `OrderBy` | dropdown: `0` CreateTime, `1` FileName | `0` | Upload order when scanning. |
| `TempNameTemplate` | string | `.%FILENAME%.tmp` | Remote name used while uploading; the file is renamed to its real name when complete. Must contain `%FILENAME%`. Empty = upload directly under the real name. |
| `ExistingRemoteFile` | dropdown: `1` Skip, `2` Overwrite, `3` Fail | `1` | What to do when a file with the same name already exists remotely. |
| `PostProcessing` | dropdown: `1` None, `2` Delete, `3` MoveToGroup, `4` MoveToArchive | `1` | What to do with the local file after it was uploaded. |
| `PostProcessFileGroup` | folder (FolderExplorer) | | Required for `3` / `4`. Target folder relative to the data folder (MoveToGroup) or to the archive folder (MoveToArchive). |
| `ParallelUploadCount` | integer (1-16) | `1` | Number of files uploaded at the same time, each upload uses its own connection. |
| `LogFileInfo` | boolean | `false` | Log name and size of every uploaded file. |

## Behaviour

- On `NoInputData` the top level of `LocalFileGroup` is scanned (no subfolders). Files whose name starts with `.` are skipped, so partially written files (e.g. Collect files' `.name.tmp`) are never uploaded. If a scan is still running, a new scan request is ignored.
- On `ViaFileInfo` only that file is uploaded; it may be in any folder. A missing file raises an error.
- For each file:
  1. The remote file with the same name is checked: `Skip` leaves the local file untouched (it is checked again on the next run), `Fail` stops the run with an error, `Overwrite` continues.
  2. The file is uploaded to `TempNameTemplate` and then renamed to its own name (an existing remote file is deleted first with `Overwrite`). If the rename fails, the temporary remote file is removed.
  3. `PostProcessing` is applied, only to files that were actually uploaded. `MoveToArchive` stores the file in `<archive>/<PostProcessFileGroup>/yyyyMMdd/`. An existing file with the same name in the target gets the suffix `_yyyyMMdd_HHmmss`.
- The existence check and the upload are retried up to 3 times (1 s, 2 s delay), the connection is reopened when needed.
- The first file that cannot be uploaded stops the run (also the other parallel uploads) with `DistributeFilesException`; `Continue` is not called. The remaining files are uploaded on the next run.
- A summary (uploaded / skipped count) is logged after every run.
- Progress: a folder scan (`NoInputData`) shows `done/total files` while uploading and `N/M files distributed` at the end; a single `ViaFileInfo` upload shows no progress.

## Notes

- With `PostProcessing = None` the files stay in `LocalFileGroup` and are uploaded again on every scan. Use `Skip` (default) to upload each name only once per remote folder, or a move / delete post-processing.
- The remote file name is always the local file name; files from different local folders with the same name end up as one remote file.
- FTPS accepts any server certificate, SFTP accepts any host key (no verification). Use expression settings (`=Secrets.SftpPassword`) for secrets.
- With `ParallelUploadCount` > 1 the upload order is not guaranteed.

## Example

```json
{ "TransferProtocol": 2, "RemoteHost": "sftp.partner.com", "UserName": "viaducta", "Password": "=Secrets.SftpPassword",
  "RemotePath": "/incoming", "CreateRemotePath": true, "LocalFileGroup": "/outbound/partner", "FileNamePattern": "*.csv",
  "PostProcessing": 4, "PostProcessFileGroup": "/outbound/partner" }
```

Timer → **Distribute files** → ...

Collect files → **Distribute files** (`Input`, `ViaFileInfo`) → ... (forwards every collected file)
