> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sequentum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use a Destination from a script

> Deliver files and rows through a Destination your organization already configured, so no credential lives inside the Agent.

A **Destination** is a remote store your organization configures once in Control Center under **Destinations**: an SFTP server, an S3 bucket, an Azure Storage account, a Google Drive folder, a Snowflake stage, or a Google Sheet. Its credentials are encrypted and only ever used inside the run proxy.

A script in an Agent never needs those credentials. It names the Destination, and the proxy performs the transfer. Nothing in the Agent, its scripts, or its logs can read the credential back.

There are two ways to use this, and most Agents only need the first.

> [!NOTE]
>
> Both work in JavaScript, C# and Python. Every example below is shown in all three.

## 1. Route export files with a Files Transformation Script

If all you need is to send each run's output files to a folder you compute, for example from an input parameter, you do not need to upload anything yourself. Every FTP, S3, Azure Storage and Google Drive export command has a **Files Transformation** script. Enable it, and before delivery it receives the files the run is about to deliver and returns where each one goes.

Each file has a local path, a `kind` (`Data` for exported data files, `Extracted` for downloaded files), the name of the export command that produced it, a `remoteFolder` relative to the Destination's configured folder, and a `remoteName`. Change the folder or the name, or leave a file out of the returned list to skip it.

This example sends every file to `<Path>/<inputfile>/results`, where `Path` and `inputfile` are input parameters of the Agent:

```javascript JavaScript theme={null}
function transformFiles(context, files)
{
    var folder = context.globalData.getString("Path") + "/" + context.globalData.getString("inputfile") + "/results";
    for (var i = 0; i < files.length; i++) {
        files[i].remoteFolder = folder;
    }
    return files;
}
```

```csharp C# theme={null}
using System.Collections.Generic;

public List<DeliveryFile> TransformFiles(ExportContext context, List<DeliveryFile> files)
{
    var folder = context.GlobalData.GetString("Path") + "/" + context.GlobalData.GetString("inputfile") + "/results";
    foreach (var file in files)
    {
        file.RemoteFolder = folder;
    }
    return files;
}
```

```python Python theme={null}
from se_scripting_utils import *

def transform_files(context: ExportContext, files):
	folder = context.global_data.get_string("Path") + "/" + context.global_data.get_string("inputfile") + "/results"
	for file in files:
		file["remote_folder"] = folder
	return files
```

The script runs once per Destination, with that Destination's stored credentials. If it fails, only that Destination's delivery fails; the rest of the export is unaffected. Use **Test Script** in the Editor to run it against sample files before saving.

## 2. Transfer from any script with `destinations`

When a script needs more than routing, for example to upload files it generated itself, to send the same output to a Destination that is not an export command of the Agent, to read a Sheet, or to pick up an input file from an SFTP server at the start of a run, use the `destinations` object on the script context. It is available in Script commands, in Export Scripts and in Files Transformation scripts.

| Operation | JavaScript | C# | Python | Returns |
| - | - | - | - | - |
| List one folder | `destinations.list(name, folder?)` | `Destinations.List(name, folder)` | `destinations.list(name, folder)` | entries with `Name`, `Size`, `Modified` |
| Download one file | `destinations.download(name, path)` | `Destinations.Download(name, path)` | `destinations.download(name, path)` | the local path it was written to |
| Upload files | `destinations.upload(name, paths, folder?)` | `Destinations.Upload(name, paths, folder)` | `destinations.upload(name, paths, folder)` | bytes transferred |
| Read rows | `destinations.readRows(name, tab?)` | `Destinations.ReadRows(name, tab)` | `destinations.read_rows(name, tab)` | rows of string cells |
| Append rows | `destinations.appendRows(name, rows, tab?)` | `Destinations.AppendRows(name, rows, tab)` | `destinations.append_rows(name, rows, tab)` | rows appended |

File Destinations (FTP, FTPS, SFTP, S3, Azure Storage, Google Drive, Snowflake) answer `list`, `download` and `upload`. Row Destinations (Google Sheets) answer `readRows` and `appendRows`. Email Destinations cannot be used from a script.

This Export Script uploads the run's data files to the Destination named **Client SFTP**, under a folder computed from an input parameter. Nothing about the server or its login appears in the Agent:

```javascript JavaScript theme={null}
function exportScript(context)
{
    var folder = context.globalData.getString("Path") + "/results";
    var files = context.exportFiles.getDataFiles().ToArray();
    var bytes = context.destinations.upload("Client SFTP", files, folder);
    context.log("Uploaded " + bytes + " bytes to " + folder);
    return true;
}
```

```csharp C# theme={null}
public bool ExportScript(ExportContext context)
{
    var folder = context.GlobalData.GetString("Path") + "/results";
    var files = context.ExportFiles.GetDataFiles().ToArray();
    var bytes = context.Destinations.Upload("Client SFTP", files, folder);
    context.Log($"Uploaded {bytes} bytes to {folder}");
    return true;
}
```

```python Python theme={null}
from se_scripting_utils import *

def export_script(context: ExportContext):
	folder = context.global_data.get_string("Path") + "/results"
	files = context.export_files.get_data_files()
	bytes = context.destinations.upload("Client SFTP", files, folder)
	context.log(f"Uploaded {bytes} bytes to {folder}")
	return True
```

A failed transfer raises an ordinary error the script can catch. Uncaught, it fails the script, and the run log carries the reason without the Destination's host or credential.

## Which Destination a name selects

The name is looked up among the Destinations of the Agent's organization, so use it exactly as it appears in Control Center. If the Agent itself contains an export command with that same name, for example an SFTP export configured inline in the Agent, that command's connection is used instead, so a script keeps working whether the connection lives in Control Center or in the Agent. A name that matches nothing fails with `No destination named '...' exists in this organization.`

## How folders resolve

* **Every path is relative to the Destination's configured folder.** `results/2026` on a Destination whose folder is `exports` writes to `exports/results/2026`. A leading slash is ignored, and `..` is rejected, so a script cannot leave the Destination's folder.
* **Placeholders in the Destination's folder are expanded.** If the Destination's folder is `exports/{ConfigName}/{yyyyMMdd}`, a script transfer resolves against today's folder for this Agent. `{ConfigName}`, `{ConfigId}` and .NET date formats such as `{yyyyMMdd}` are supported, and spaces in the expanded folder become underscores. A Destination folder without placeholders is used exactly as typed.
* **The folder your script passes is used as typed.** Placeholders in it are not expanded. Compute the value in the script instead.
* **Missing folders are created** on SFTP, FTP, Azure file shares and Google Drive. On S3 the folder is a key prefix, so nothing needs creating.
* **Files keep their local name.** To deliver under another name, rename the local file first, or use a Files Transformation Script, which can set `remoteName` directly.

## Limits

| | Limit |
| - | - |
| Upload, per call | 500 MB in total across the files |
| Download, per file | 500 MB |
| Listing | 10,000 entries |
| Append rows, per call | 50,000 rows or 500,000 cells |
| Read rows | truncated at 50,000 rows |
| Time, per call | 600 seconds, so a 500 MB upload needs roughly 7 Mbps |

## Testing in the Editor

**Test Script** runs the real transfer with your own user's access to the organization's Destinations, so an upload during a test really lands on the server. Two differences from a run: a Destination declared inside the Agent is not available while designing, and an Export Script sees no export files at design time, so test uploads of `getDataFiles()` with a Script command or with literal paths.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.