Skip to content

SFTP ​

An SFTP data source connects ApiMeld to an SSH file transfer server. Scripts can list, read, upload, and manage files — subject to the permissions of the configured SFTP account — on any SFTP-accessible host including on-premises servers, cloud storage gateways, or hosted SFTP services.

Setting up an SFTP data source ​

  1. Go to Data Sources → New Data Source
  2. Select SFTP
  3. Fill in the connection details:
FieldDescription
NameHow scripts reference this connection (e.g. VendorSftp)
HostHostname or IP of the SFTP server
PortDefaults to 22
Base PathOptional base directory to scope all operations (e.g. /uploads). Scripts cannot navigate above this path.
UsernameSFTP username
PasswordPassword authentication (stored encrypted). Leave blank if using a private key.
Private KeyPEM-format private key for key-based authentication (stored encrypted).
PassphrasePassphrase for the private key, if it is encrypted.
Host FingerprintExpected server fingerprint (e.g. SHA256:abc123...). When set, connections are rejected if the server presents a different key — protects against MITM.
  1. Click Test Connection to verify
  2. Save

Key-based authentication

Private key authentication is more secure than passwords for SFTP. Generate a key pair, add the public key to the server's authorized_keys, and paste the private key (PEM format) into ApiMeld. The private key is stored AES-256-GCM encrypted.

Host fingerprint

Set the Host Fingerprint for any production SFTP connection. You can get the fingerprint by running ssh-keyscan -t ed25519 your-sftp-host and noting the hash, or from your SFTP provider's documentation.

Available methods ​

All paths are relative to the configured Base Path. Write operations (Upload, DeleteFile, MoveFile, Mkdir, Rmdir) will fail if the configured credentials only have read access on the SFTP server — what ApiMeld can do is limited by the permissions granted to the SFTP account.

MethodDescription
List(path?, pattern?)List files and directories. Optional glob pattern (e.g. *.xml).
Exists(path)Returns true if the file or directory exists.
ReadRaw(path)Read file contents as a string.
ReadCsv(path, delimiter?)Parse a CSV file and return an array of row objects.
ReadExcel(path, sheet?)Parse an Excel file (.xlsx) and return an array of row objects.
TempPath(path)Download the file to a local temp path and return that path.
Upload(path, content)Write a string to a remote file (creates or overwrites).
DeleteFile(path)Delete a remote file.
MoveFile(sourcePath, destPath)Move or rename a file on the server.
Mkdir(path)Create a remote directory.
Rmdir(path)Remove a remote directory.

Upload vs WriteFile

SFTP uses Upload / upload where Network Share uses WriteFile / writeFile. Everything else is the same.

List() returns an array of objects with: name, isDirectory, sizeBytes, modifiedAt.

File reads are subject to a configurable size limit (default 25 MB). An admin can raise this under Admin → Settings → Storage.

PowerShell examples ​

powershell
# List all XML files waiting to be processed
$files = $datasources.VendorSftp.List("Incoming", "*.xml")
$logger.Info("Files waiting: $($files.Count)")

# Read a remote file as text
$content = $datasources.VendorSftp.ReadRaw("Incoming/orders.xml")

# Read a CSV from the SFTP server
$rows = $datasources.VendorSftp.ReadCsv("Exports/daily.csv")
$logger.Info("Rows received: $($rows.Count)")

# Upload a result file back to the server
$datasources.VendorSftp.Upload("Outgoing/processed.csv", "id,status`n1,ok`n2,ok")

# Download to a temp path for tools that need a real file path
$localPath = $datasources.VendorSftp.TempPath("Incoming/report.xlsx")
$data = Import-Excel -Path $localPath

# Archive after processing
$datasources.VendorSftp.MoveFile("Incoming/orders.xml", "Archive/orders.xml")

JavaScript / TypeScript examples ​

javascript
// List incoming files
const files = await datasources.VendorSftp.list('Incoming', '*.xml')
logger.info(`Files waiting: ${files.length}`)

// Read a remote CSV
const rows = await datasources.VendorSftp.readCsv('Exports/daily.csv')
logger.info(`Rows received: ${rows.length}`)

// Upload a result file
const output = rows.map(r => `${r.id},processed`).join('\n')
await datasources.VendorSftp.upload('Outgoing/results.csv', `id,status\n${output}`)

// Archive the source file
await datasources.VendorSftp.moveFile('Exports/daily.csv', 'Archive/daily.csv')

Common patterns ​

Download, process, and acknowledge ​

powershell
$files = $datasources.VendorSftp.List("Incoming", "*.csv")

foreach ($f in $files) {
    $rows = $datasources.VendorSftp.ReadCsv("Incoming/$($f.name)")

    # Process rows — insert into DB, call an API, etc.
    foreach ($row in $rows) {
        # ...
    }

    # Write an acknowledgement file and archive the source
    $datasources.VendorSftp.Upload("Ack/$($f.name).ack", "processed")
    $datasources.VendorSftp.MoveFile("Incoming/$($f.name)", "Archive/$($f.name)")
    $logger.Info("Processed: $($f.name)")
}

Only process if file exists ​

javascript
const path = 'Incoming/nightly-export.csv'

if (await datasources.VendorSftp.exists(path)) {
  const rows = await datasources.VendorSftp.readCsv(path)
  logger.info(`Processing ${rows.length} rows`)
  await datasources.VendorSftp.moveFile(path, `Archive/nightly-export.csv`)
} else {
  logger.warn('Nightly export not yet available — will retry next run')
}