SFTP is not dead: bank files and billing exports
Banks, lockbox processors and billing vendors still deliver files over SFTP. Here is how to read them safely, check every row, and stop someone from re-keying payments.
Every few years someone announces that file transfers are over and everything will be an API. Then the bank sends the daily payment file to an SFTP folder, the same way it has for fifteen years. For most cities, SFTP is still how money arrives.
That isn't a failure to modernize. A file is a clean, auditable handoff between two organizations that don't share systems. The trouble is usually what happens after the file lands.
Where file handoffs go wrong
The typical setup is a script someone wrote years ago, or a person who opens the file each morning and keys it in. Both work until they don't:
- A file arrives twice, and payments are posted twice.
- A row has a blank account number, and the whole load fails at 6:05 am.
- The script's author has left, and nobody knows which folder it reads.
- The server's identity changes, and nobody notices the script is now talking to something else.
None of these are hard problems. They just need to be handled the same way every time.
Five habits of a good file flow
1. Check who you're talking to
SFTP servers have a host key, a fingerprint that proves the server is the one you expect. A good flow saves that fingerprint when you first connect and refuses to continue if it ever changes. That's called host-key pinning, and it's the difference between "encrypted" and "encrypted to the right party".
2. Only read files once
Read only files that are new since the last good run, and move each file to an archive folder after a successful load. If the run fails, the file stays where it was, so the next run picks it up again. No one has to remember what was already posted.
3. Check every row before it lands
Bank files are mostly clean. Mostly. Before a row goes into the finance database, check it:
- Trim and upper-case the account number, then require it.
- Make sure the amount is a number, and within a sensible range.
- Make sure the date is a real date.
Rows that fail shouldn't stop the whole file. They should go to a person, with the reason.
4. Make loads repeatable
Load with an upsert on a key the bank provides, such as the receipt number. If the same row is ever loaded twice, it updates instead of duplicating. That one choice removes most double-posting risk.
5. Keep the file name with each row
When finance asks where a payment came from, the answer should be "row 41 of utility-payments-2026-09-14.csv", not "the import". Adding the source file name to each record makes that question easy.
What it looks like as a flow
Here is the ready-made bank payments flow in SentraBridge. It runs weekdays at 6 am, reads new CSV files matching utility-payments-*.csv, cleans and checks each row, upserts good rows into a utility_payments table keyed on the receipt, and moves the file to archive. Rows that fail go to finance by email, with a CSV of just those rows attached.
The rules step has two outputs, Valid and Invalid, so the bad rows take a different wire instead of stopping the run. The email line for each bad row reads like {{source_file}} {{receipt}}: {{rule_errors}}, so finance sees the file, the receipt and the reason.
Not just CSV
Vendors send what they send. A file flow should read the common formats without a custom parser for each:
- CSV with comma, semicolon, tab or pipe separators, with or without a header row.
- JSON, including a list inside the file (for example, an
inspectionsarray). - JSON Lines, one record per line, common in exports from newer systems.
- XML, where you name the record element, such as
payment.
The same is true going the other way. A nightly export of yesterday's 311 requests, written as a dated CSV in an outbox folder, is often the simplest way to feed a billing or work-order system that only takes files.
Moving documents, not just rows
Some handoffs are whole documents: permit PDFs, signed agreements, scanned forms. Those can move the same way, downloaded and uploaded in memory with their metadata, without a copy left on a shared drive along the way. See files and documents for the Transfer file step.
Where SentraBridge fits
SentraBridge treats SFTP as a first-class connector, not an afterthought. Host keys are pinned and checked on every connection. Files are read in memory and never stored by SentraBridge; run history keeps the file names, counts and record IDs, not the payment details. You can preview a real file in the data inspector before turning the flow on, and nothing is written during preview.