HubSpot + SFTP and CSV vendor feeds integration
A nightly CSV on an SFTP server is all some ERPs, payroll platforms, carriers, 3PLs and custodians will ever give you, with no endpoint to call.
Built by us- Into HubSpot
Is there a HubSpot app for SFTP and CSV vendor feeds?
No. Each vendor's file feed is specific to the vendor sending it, so the HubSpot App Marketplace has nothing generic to list, as of September 2026. When a vendor's only export is a scheduled CSV drop, the route is a pipeline you own, and we have built one. Budget 10 to 20 hours of discovery and 70 to 150 hours of build.
- Recommended route
- Custom middleware
- Build effort
- 70 to 150 hours
- In the HubSpot App Marketplace?
- No listed app
- Typical elapsed time
- 4 to 8 weeks
Marketplace checked September 2026.
Why teams connect SFTP and CSV vendor feeds to HubSpot
Plenty of the systems a business depends on have no API at all. You find them across industries, among legacy ERPs, payroll and HR platforms, carriers and 3PLs, point of sale back offices, and custodians and fund platforms. They publish scheduled reports instead: a handful of CSV files dropped on an SFTP server overnight, named by report and date. The data is complete and the cadence is reliable. There is no endpoint to call and no event to subscribe to.
Sales and service teams working in HubSpot feel this as a missing half of the relationship. HubSpot knows the prospect, the meetings and the paperwork. It does not know what the customer bought, holds or owes, what changed since the last file, or which order an email thread relates to. So whoever owns the account opens the source system, or asks operations for an export, and HubSpot becomes the place where notes live rather than where the relationship lives. No workflow can fire on data HubSpot never sees.
Loading the feed changes what HubSpot is for. Once orders, invoices, shipments or holdings sit as records against the contact, you can list the accounts with an overdue invoice, route a review to the right owner, or read engagement activity beside the money it relates to. The work is unglamorous and almost entirely about discipline. The same files, parsed the same way every night, with something watching that speaks up when one does not arrive.
What syncs
Files rather than objects are the unit of delivery, so the mapping starts one level up. Each file gets a shape: which columns identify the record, which columns carry values, and what the file means when a row disappears from it. A missing row in a snapshot file, such as balances or stock levels, usually means the record closed. A missing row in a contact file usually means the vendor sent a delta. Getting that distinction wrong deletes real records.
The object model underneath is conventional. Customers become contacts, the parent account becomes a company, product detail fills the product library, and activity arrives as engagements. Anything that is an order, a transaction or a snapshot becomes a custom object associated to the contact. HubSpot’s custom object API accepts a batch upsert against a unique identifier property, which is exactly what a nightly file needs. The vendor’s account number goes in that property, and the same file loaded twice produces the same records instead of a second set. Nothing keys on a name, because two files from one vendor will spell the same customer two ways.
| | | Direction | Match key | Notes |
|---|---|---|---|---|
| Customer or account row | Contact | Into HubSpot | Vendor account number in a unique property on the contact | Never the name. The same customer is spelled two ways across two files. |
| Company or parent account row | Company | Into HubSpot | Vendor company id, associated to each of its contacts | |
| Order or transaction row | Custom object | Into HubSpot | Vendor order or transaction id, associated to the contact | |
| Balance or stock-level snapshot row | Custom object | Into HubSpot | Account number plus item identifier | A missing row usually means the record closed. Confirm it before acting. |
| Product or item detail row | Product | Into HubSpot | Vendor product code or SKU | |
| Activity or event row | Engagement | Into HubSpot | Vendor activity id, associated to the contact |
Architecture
The shape is a managed transfer service in front of object storage, with a state machine doing the work. AWS Transfer Family gives each vendor a real SFTP endpoint, reached with the client and key they already use, writing straight into a storage prefix. A new object raises an event, and that event starts a Step Functions execution.
Three functions run in order inside it. An extractor reads the file, parses it, and moves it into a processing prefix so a retry cannot pick it up twice. A validator checks the headers, remaps the vendor’s field names onto HubSpot property names, and applies the rules that decide whether a row is usable. A loader batches the validated rows into HubSpot keyed on the source identifier, then makes a separate pass for associations. On success the file moves to a processed prefix, and on failure to a failed one, so the prefix a file sits in is the run’s state. Step Functions carries retry and catch around each step, and a failed execution raises an alert rather than ending quietly.
-
Vendor
-
SFTP and CSV vendor feeds The vendor's own SFTP client and key
-
-
Transfer and storage
- SFTP endpoint AWS Transfer Family, one per vendor
- Object storage A new object raises an event
-
Step Functions
- Extractor Parses, then moves to processing
- Validator Headers, field names, row rules
- Loader Keyed batches, then associations
-
CRM
-
HubSpot Contacts, companies, custom objects
-
What the API allows
- API style
- File transfer
- Authentication
- SFTP credentials
- Webhooks
- No
- Changed-since filter
- No
- Sandbox
- Yes
- Rate limit
- None on the file side. HubSpot's per-app limits govern the load.
Developer documentation docs.aws.amazon.com
Three ways to connect
What decides here is who owns the file’s shape, and how much judgement the load needs. If the file is small, stable and lands in a single standard object, a file-aware integration platform can watch the folder and map the columns with no code. That covers more cases than engineers like to admit, and it is cheaper when it fits.
That platform stops fitting once the load needs judgement. Several files that must land in a fixed order, custom objects with associations back to a contact, rows that are valid alone and wrong together, or a vendor that renames a header without telling anyone: each turns a mapping tool into a maintenance job. Where the data is money, the pipeline you own usually wins, because you need the run history as much as the load.
-
Custom middleware
RecommendedA managed transfer endpoint, object storage and a state machine give you the run history, the retry behaviour and the failed-file quarantine that a money feed needs. The validation rules live in code you can read.
-
Automation platform
PossibleA file-aware integration platform can watch a folder and map columns with no code. It fits a single small file landing in a standard object, and stops fitting when several files must load in a fixed order.
-
HubSpot Data Sync
AvoidHubSpot Data Sync connects to applications, not to a folder of files. There is no connector to point at an SFTP server, so this route does not start.
What breaks and how we prevent it
Most incidents trace back to arrival, column drift, re-delivery or the load itself.
A file that never arrives
A file that never arrives is silent, and that is the one teams underestimate. Nothing fails, no alert fires, and the data is a day stale until somebody notices in a client meeting. We watch for expected arrivals rather than only for errors. Each feed has a window, and a window that closes empty raises the same alert a parse failure would.
Column drift between releases
Vendors rename a header, add a column, or change a date format between releases, and a loader that trusts column position writes the wrong value into the right property. The validator matches on header names, refuses a file whose required headers are missing, and reports the difference instead of loading half of it.
The same file arriving twice
The same file arrives twice, or the vendor resends a corrected version of last night’s extract. Because every write is an idempotent batch upsert keyed on the vendor’s identifier, the second load updates rather than duplicates, and moving files between prefixes stops a retry from processing one object twice.
A load that fails partway
The load itself can fail too. HubSpot counts rate limits per app rather than per portal, so a backfill and a nightly run compete. We batch, pace the loader, and keep the association pass separate, so a partial failure leaves records that are correct but not yet linked. A replay finishes them.
Our approach
- Scope. We collect one real sample of every file, agree what each one means when a row is absent, and confirm which vendor field is the stable identifier.
- Architect. We fix the object model before any code: which rows are contacts, which become custom objects, and how associations run back to the customer record.
- Build. The extractor, validator and loader, with the field mapping held outside the code so a vendor’s rename is a configuration change. A local harness runs the whole pipeline against fixtures with nothing sent anywhere.
- Validate. Loads run against a HubSpot sandbox first, behind a fail-closed portal allowlist, so a misconfigured token cannot write to the wrong portal. Production cutover is a token swap.
- Operate. Arrival monitoring per feed, a failed prefix that is also the replay queue, and a reconciliation count that compares rows delivered against records written.
Common questions
Is there a HubSpot app that imports a vendor's SFTP file feed?
Searching the HubSpot Marketplace for this finds nothing to install, which is expected. A file feed is an integration shape rather than a product, so no vendor publishes an app for it. The connection is always something built around the specific files a vendor sends.
Why not use the HubSpot import tool for a recurring CSV?
The import tool is built for one-time loads by a person. It has no schedule, no validation rules of your own, no retry, and no record of what happened last night. A recurring vendor feed needs all four, and it needs them to run at 2am without anyone logged in.
What happens when a vendor changes a column in the CSV?
The validator refuses the file rather than loading part of it. Matching happens on header names instead of column position, so a renamed or added column is detected before any write. The run reports which headers were expected and which arrived, and the file moves to a failed prefix where it can be replayed after the mapping is updated.
How do you avoid duplicate contacts when the same file is delivered twice?
Every write is a batch upsert keyed on the vendor's account number held in a unique HubSpot property, so loading the same file again updates the same records. The pipeline also moves each file between processing, processed and failed prefixes, so a retry cannot pick up an object that is already in flight.
Where should transactions from a vendor feed live in HubSpot?
On custom objects associated to the contact, not on the contact itself. One customer can have many orders and thousands of transactions, and flattening them into contact properties destroys the history and hits property limits fast. Custom objects keep each row addressable and let a list or workflow filter on them directly.
How often can an SFTP feed load into HubSpot?
As often as the vendor publishes, because the load starts when a file lands rather than on a clock. Most vendor feeds are nightly, and some are weekly. The pipeline reacts within seconds of the upload completing, so the practical limit is the vendor's schedule rather than anything on the HubSpot side.
What does the pipeline do with a file that fails validation?
It quarantines it. The file moves to a failed prefix, the state machine execution ends in a failed state, and an alert goes to the delivery channel with the reason. Nothing partial is written to HubSpot. Once the mapping is corrected, the same file is replayed from the failed prefix and loads normally.
How many hours does an SFTP to HubSpot pipeline take to build?
A feed of several files landing in contacts plus custom objects with associations runs 10 to 20 hours of discovery and 70 to 150 hours of build. A single file into a single standard object sits well below that. Most of the range is validation rules, association ordering and the operational pieces.
Also in Data and sync platforms
Related reading
Partnerships and accreditations
HubSpot accreditations
Industry specializations
Partnerships
Scope a SFTP and CSV vendor feeds integration
Send the systems, the direction and the record volume. We reply with a scope and an effort band within one business day.
Thanks, we will reply within one business day
Prash or Sean reads every one of these and comes back with a scope, or with the one question we need answered first.
Where these facts come from
- What is AWS Transfer Family? docs.aws.amazon.com
- What is Step Functions? docs.aws.amazon.com
- Custom object records API guide developers.hubspot.com