SFTP adapter
Two adapters over one SFTP server. The Listener polls a directory and publishes a message per file; the Caller writes one file per message. The Authentication carries the credentials and the expected host key.
SFTP is not one adapter with two modes. It is two adapters that share a path model and a set of Authentications: the SFTP Listener goes on a receive port, the SFTP Caller on a send port. The Host and Port sit on the adapter, so one credential can serve several ports and each port states its server explicitly; the credentials and the expected host key belong to the Authentication.
Both adapters pair with an Authentication built on the SFTP Password Authentication Definition. It is the only Definition; there is no key-based shape.
| Setting | Value |
|---|---|
| Name | Your name for the Authentication, no spaces or punctuation |
| Adapter | SFTP Listener, or SFTP Caller |
| Definition | SFTP Password Authentication |
| Application | Preset, the Application you are working in |
| Username | Required. Under SFTP Password Settings, in the Credentials group. |
| Password | Required, with a reveal toggle. Same group. |
| Host Key Fingerprint | Optional. Under SFTP Password Settings, in the Server Identity group. |
Host Key Fingerprint is optional on the Authentication and belongs in every production configuration. When it is set, the adapter refuses to connect to a server whose host key does not match. This is the SFTP equivalent of certificate pinning: if the partner replaces their server key without telling you, the connection fails instead of trusting whatever answers.
Path is a location on the server. On the Listener it is the directory to poll; on the Caller it is the file to write, filename included.
| Rule | Behaviour |
|---|---|
| Separators | Forward slashes, as the server expects them. A leading slash means the server root; without one the path is relative to the directory the account lands in when it signs in, which on most partner servers is a home or chroot directory rather than the root. |
| Wildcards | * and ? only, and only in File Mask. No character classes, no regular expressions. Everything else in the mask is matched literally. |
| What a mask matches | The entry name, never the full path, and case is ignored. *.csv matches PRICES.CSV; outbound/*.csv matches nothing, because no entry is named with a slash in it. |
On its own interval the Listener lists the directory, takes as many files as its two budgets allow, reads each one, removes it from the server, and publishes it to the bus as a separate message.
| Field | Default | What it does |
|---|---|---|
| Auth Config Type | Static | The only option on a receive port. |
| Auth Config | Required | The Authentication that supplies the username, password and expected host key. |
| Host | Required | The SFTP server to connect to, by name or address. |
| Port | 22 | The SSH port on that server. |
| Polling Interval (seconds) | Required, 1 or more | How long to wait between polls. The next poll is scheduled from the moment the current one starts, so a slow poll does not push the following one further out. |
| Max Files Per Poll | Required | A hard stop. Once this many files are published the pass ends and the remainder waits. |
| Max Batch Size in Bytes | Required | Total bytes one pass may deliver. There is no unlimited setting. |
| Path | Empty | The directory to poll. Empty means the directory the account lands in when it signs in. |
| File Mask | * | Which file names to take. |
| Include Subfolders | Off | Poll one directory level only. Turn it on to walk every subdirectory under Path. |
The Listener lists files only, so a directory whose name happens to match the mask is never picked up as if it were a file. The body it publishes is the file content, and each message carries FileName, FilePath and FileSize as context properties. FilePath is how you tell two files of the same name in different subdirectories apart when subfolders are included.
The Caller does one thing: it writes the message body to the server as a file. Upload is the only operation. The port's whole job is deciding where the file lands and how the body becomes bytes.
| Field | Default | What it does |
|---|---|---|
| Auth Config Type | Static or Dynamic | Static names one Authentication on the port, Dynamic resolves it per message. |
| Auth Config | Required | The Authentication that supplies the username, password and expected host key. |
| Host | Required | The SFTP server to write to, by name or address. |
| Port | 22 | The SSH port on that server. |
| Path | Required | The file to write, filename included. |
| Overwrite | On | When off, an Upload aimed at an existing file fails instead of replacing it. |
| Create Directory If Not Exists | On | Creates the directories above the target. When off, a missing directory fails the Upload. |
| Request Payload Mode | Auto | How the message body becomes the bytes that get written. Auto is not implemented, so set Text or Base64. |
No atomic write, and what to offer a partner who needs one
An Upload writes to Path directly. There is no temporary name, no rename into place, and no field for a temp suffix. A partner watching the destination directory can therefore see a partially written file, and a connection that drops halfway leaves a short one behind.
Do not promise a partner that they never see a half-written file. What you can honestly offer instead: a dropped upload is always a failed run, so it lands in Tracking and on the exception route, and a replay rewrites the whole file. The partner's own pickup should wait for a marker file, or read from a directory you only move finished work into by other means.
There is no in-product workaround. Upload is the Caller's only operation, so the old advice of uploading to a temporary path and then issuing a Move no longer applies.
Upload in detail: the two guards
Overwrite off is a check made before the write, not a lock. It fails the operation if the file is already there, which is what you want for a partner drop where a repeat means a duplicate. It cannot promise that nothing else created the file between the check and the write, so treat it as a guard against your own duplicates rather than as mutual exclusion.
Create Directory If Not Exists builds every missing directory above the target, one level at a time. It does nothing for a file written straight into the sign-in directory, because there is no directory above it to make.
Request Payload Mode: which one to set, and why Auto is not one of them
The mode applies only to a body that is text or an object. A body that is already raw bytes is written as it stands whatever the mode says, and an empty body writes an empty file.
| Mode | What gets written |
|---|---|
| Auto | Not implemented. It is a planned feature, so do not leave the field on it. Set Text for character files and Base64 for binaries. |
| Text | The body is written as UTF-8 text. This is the one for CSV, XML, JSON and any other character file. |
| Base64 | The body is treated as Base64 and decoded before writing. This is the one for binaries: a PDF carried through the bus as Base64 lands on the server as the real file. It applies only when the body is a string, and an invalid Base64 string fails the operation. |
| Json | The body is serialised as JSON. A string body comes out quoted and escaped, which is rarely what you want for a file. |
What comes back, and what the port promotes
The response body is an echo of the request body, not the stored file. A success means the bytes were accepted by the server, nothing more.
The port promotes Path and FileName, so a later step can name the file it just wrote. The values are attached before the write runs, which means they are there on a failed response too.
Where a problem surfaces decides what the platform does with it, and only failed responses are retried.
| Kind of failure | Retried? | What happens |
|---|---|---|
| Configuration | No | A missing Host, or a Path the adapter cannot resolve, is rejected outright rather than returned as a failed response. |
| Missing credentials | No | An Authentication without a username or password. The SSH session is built before the transfer is attempted, so this escapes the retry loop too. |
| Rejected credentials | Once | The server refuses the username or password. The platform refreshes the credential and tries again, so a password corrected on the Authentication recovers without a restart. |
| Host key mismatch | No | The server's host key does not match the Host Key Fingerprint on the Authentication. This is a refusal to trust, not a transient fault, so retrying it is pointless and the connection is abandoned. |
| Anything the server refuses | Yes | A file that already exists with Overwrite off, a missing directory with Create Directory If Not Exists off, a permissions refusal, or any transport error. |
That is the SFTP adapter
A Listener that polls and consumes, a Caller that uploads and nothing else, and an Authentication that carries the credentials and pins the host key. Remember the Listener always deletes, and that an Upload is not atomic. Back to Adapters.