---
url: /process-functions/ftpclient.md
description: Transfers files and manages directories on a remote FTP, FTPS or SFTP server.
---

# &#x20;FTPClient

Transfers files and manages directories on a remote FTP, FTPS or SFTP server.

```js
const client = ftp.ConnectWithSecret("sftp", "files.partner.com", 22, "modlr", "PARTNER_SFTP_KEY");

if (!client.IsConnected()) {
    script.fail("Could not connect to the partner SFTP server.");
}

client.Download("/outbound/sales.csv", "uploads/sales.csv");
```

## Constructors

There are three ways to connect, depending on how the server authenticates. All three take the same first four parameters:

| Parameter | Type | Description |
|---|---|---|
| `protocol` | `string` | `"ftp"`, `"ftps"` (FTP over TLS) or `"sftp"` (SFTP over SSH). Any other value is treated as `"ftp"`. |
| `hostname` | `string` | The server's host name or IP address. |
| `port` | `number` | The port to connect on. There's no default: usually `21` for FTP and FTPS, and `22` for SFTP. |
| `username` | `string` | The user name to log in with. |

A failed connection is logged rather than thrown, so check [IsConnected()](#isconnected) before transferring anything.

### ftp.ConnectWithSecret `ftp.ConnectWithSecret(protocol, hostname, port, username, keySecret, passphraseSecret)`   {#ftp-connectwithsecret}

Connects to an SFTP server with a private key stored as a [Secret](/process-functions/security-getsecret). This is the preferred way to use a key: you pass the secret's name, so the key never appears in the process.

| Parameter | Type | Description |
|---|---|---|
| `keySecret` | `string` | The name of the secret holding the private key. |
| `passphraseSecret` | `string` | Optional. The name of the secret holding the key's passphrase. Leave it out when the key isn't encrypted. |

```js
const client = ftp.ConnectWithSecret("sftp", "files.partner.com", 22, "modlr", "PARTNER_SFTP_KEY");

// A passphrase-protected key
const client = ftp.ConnectWithSecret("sftp", "files.partner.com", 22, "modlr", "PARTNER_SFTP_KEY", "PARTNER_SFTP_PASSPHRASE");
```

### ftp.ConnectWithKeyFile `ftp.ConnectWithKeyFile(protocol, hostname, port, username, keyFile, passphrase)`  {#ftp-connectwithkeyfile}

Connects to an SFTP server with a private key file.

| Parameter | Type | Description |
|---|---|---|
| `keyFile` | `string` | The path of the private key file. |
| `passphrase` | `string` | Optional. The key's passphrase. Leave it out when the key isn't encrypted. |

```js
const client = ftp.ConnectWithKeyFile("sftp", "files.partner.com", 22, "modlr", "keys/partner_rsa");
```

### ftp.Connect `ftp.Connect(protocol, hostname, port, username, password)`  {#ftp-connect}

Connects with a user name and password.

| Parameter | Type | Description |
|---|---|---|
| `password` | `string` | The password to log in with. |

```js
const client = ftp.Connect("sftp", "files.partner.com", 22, "modlr", security.getSecret("PARTNER_SFTP_PASSWORD"));
```

## Overview

* **Check the connection:** connecting never throws, so call [IsConnected()](#isconnected) straight after connecting.
* **Check each transfer:** methods return `false` (or `null` for [Directory()](#directory)) when they fail, and write the reason to the process log. They don't throw.
* **Destination directories must exist:** [Upload()](#upload) and [Rename()](#rename) fail if the remote directory isn't there. Create it with [MakeDirectory()](#makedirectory) first.
* **Timeouts:** there's no timeout by default, so an unresponsive server can hold up a process. Set one with [SetTimeout()](#settimeout) for servers you don't control.
* **Disconnecting:** the client disconnects automatically when the process finishes.

## Methods

### IsConnected `IsConnected()`  {#isconnected}

Returns `true` when the client is connected to the server. Returns `false` if the connection failed, or after [Disconnect()](#disconnect).

### SetTimeout `SetTimeout(milliseconds)` {#settimeout}

Sets how long each operation, such as a listing or a transfer, can take before it's abandoned. An operation that times out fails like any other, returning `false` or `null`.

| Parameter | Type | Description |
|---|---|---|
| `milliseconds` | `number` | The timeout for each operation, in milliseconds. `0` means no timeout. |

### Directory `Directory(directory)`  {#directory}

Lists the files and folders directly inside a remote directory. Returns a JSON string, so read it with `JSON.parse()`. Returns `null` if the listing fails.

| Parameter | Type | Description |
|---|---|---|
| `directory` | `string` | The remote directory, for example `"/outbound"`. A trailing slash makes no difference. |

Each entry has:

* `name`: the file or folder name.
* `path`: its full remote path, ready to pass to [Download()](#download).
* `isDirectory`: `true` for folders.
* `size`: its size in bytes.

### Download `Download(remote, local)`  {#download}

Downloads a remote file. Returns `true` when the file transferred.

| Parameter | Type | Description |
|---|---|---|
| `remote` | `string` | The remote file's path. |
| `local` | `string` | The path to save it to. |

### Upload `Upload(localPath, remoteDirectory)`  {#upload}

Uploads a file into a remote directory. The file keeps its name, so pass the directory, not a file path. Returns `true` when the file transferred.

| Parameter | Type | Description |
|---|---|---|
| `localPath` | `string` | The path of the file to upload. |
| `remoteDirectory` | `string` | The remote directory to upload into. It must already exist. |

### MakeDirectory `MakeDirectory(remote)`  {#makedirectory}

Creates a remote directory. Only the last folder in the path is created, so its parent must already exist. Returns `false` if it fails, including when the directory already exists.

| Parameter | Type | Description |
|---|---|---|
| `remote` | `string` | The remote directory to create. |

### Rename `Rename(remote, remoteNew)`  {#rename}

Renames a remote file. The new path can be in a different directory, which moves the file. Returns `true` when it succeeds.

| Parameter | Type | Description |
|---|---|---|
| `remote` | `string` | The file's current remote path. |
| `remoteNew` | `string` | Its new remote path. The directory must already exist. |

### Delete `Delete(remote)`  {#delete}

Deletes a remote file. This can't be undone, so consider moving the file into an archive directory with [Rename()](#rename) instead. Returns `true` when it succeeds.

| Parameter | Type | Description |
|---|---|---|
| `remote` | `string` | The remote file's path. |

### Disconnect `Disconnect()`  {#disconnect}

Closes the connection. The client disconnects automatically when the process finishes, so only call this to end the session early. A disconnected client can't be reused; connect again to make a new one.

## Examples

### Download new files and archive them

```js
const client = ftp.ConnectWithSecret("sftp", "files.partner.com", 22, "modlr", "PARTNER_SFTP_KEY");

if (!client.IsConnected()) {
    script.fail("Could not connect to the partner SFTP server.");
}

client.MakeDirectory("/outbound/archive");

for (const entry of JSON.parse(client.Directory("/outbound"))) {
    if (entry.isDirectory || !entry.name.endsWith(".csv")) {
        continue;
    }

    if (client.Download(entry.path, "uploads/" + entry.name)) {
        client.Rename(entry.path, "/outbound/archive/" + entry.name);
    }
}
```

### Upload a report

```js
const client = ftp.ConnectWithSecret("sftp", "files.partner.com", 22, "modlr", "PARTNER_SFTP_KEY");

if (!client.Upload("exports/report.xlsx", "/inbound")) {
    script.fail("Failed to upload the report.");
}
```

### Connect over FTP or FTPS

```js
// FTP
const client = ftp.Connect("ftp", "files.partner.com", 21, "modlr", security.getSecret("PARTNER_FTP_PASSWORD"));

// FTPS (FTP over TLS)
const client = ftp.Connect("ftps", "files.partner.com", 21, "modlr", security.getSecret("PARTNER_FTP_PASSWORD"));

if (!client.IsConnected()) {
    script.fail("Could not connect to the partner FTP server.");
}
```

## Related

* [security.getSecret](/process-functions/security-getsecret): reads a stored secret, such as a password.
