When One HubSpot Account Cannot Trust Its Own Data

The architecture behind Reevia's HubSpot sync: four source systems, batch ingestion, normalization, upserts with associations, and full audit logging.

By Adriano Junior

HubSpot was already installed. It never received usable data, because four separate systems fed it and none of them agreed on who a customer was.

That is the situation behind Reevia's HubSpot integration, a project I delivered for one of Brazil's largest veterinary networks. Records arrived raw, inconsistently formatted, with no shared identifier tying the same customer across systems. The cost of that gap was not abstract: a team that stopped trusting its own CRM, duplicate contacts nobody had time to clean up, and reports nobody could fully rely on.

The fix was not a plugin. It was a pipeline, and it moved over 2 million records into one account, with a new lead reaching HubSpot in under 50 seconds and the whole build reaching production in under four weeks. A project like this, scoped to what your systems actually need, starts from $4,999. Left alone, the cost of disagreeing systems does not stay flat. It grows every week your team keeps working around a CRM they cannot fully trust.

If you want the business outcome first, read the Reevia case study. This article covers what the underlying architecture actually looked like.

TL;DR

  • Four source systems fed one HubSpot account, none sharing a common identifier across records, which is why records arrived unusable.
  • The fix processes data in batches, cleans it up, and writes it to HubSpot connected to the right company, deal, or ticket on the first pass, not as a follow-up step.
  • Every write is logged, so any HubSpot record traces back to exactly where it came from.
  • A control panel lets the team pause one source without stopping the others, and check any record end to end.
  • Over 2 million records processed. Leads reach HubSpot in under 50 seconds. Production in under four weeks.

Table of contents

  1. The problem: four systems, no shared way to identify a customer
  2. Results
  3. When you do not need this level of build
  4. For your engineer
  5. FAQ

The problem: four systems, no shared way to identify a customer

Reevia's client ran on four systems, each built for a different job: one handled scheduling, one handled billing, one tracked inventory, one ran the customer support desk. None were built to talk to HubSpot, and none shared a common customer ID.

That last part is what breaks most sync projects. Without a shared identifier, you cannot match records across systems and assume they refer to the same person or company. A customer might show up as "M. Silva" in one system, "Maria Silva Ltda" in another, and a raw internal ID with no name at all in a third. HubSpot needs one record per real customer, and getting there requires a matching plan before anyone writes anything.

This is also why "connect it to HubSpot and you are done" is bad advice for a project like this. A single-source integration can often get away with a direct call per event. Four sources writing to the same account need a pipeline that checks, deduplicates, and reconciles before anything touches HubSpot. Skip that step and you end up with duplicate contacts, orphaned deals, and a sales team that stops trusting the CRM. If you are earlier in the process and still scoping your sources, our checklist for HubSpot data migrations covers the mapping work that has to happen first.

Results

The numbers from this build: over 2 million records processed, any lead reaching HubSpot in under 50 seconds from the moment the source system produced it, and a path from kickoff to production in under four weeks.

Four weeks is fast for four source systems feeding one CRM with full connection handling and a complete audit trail. It was possible because the plan was decided early and did not change mid-build. Scope discipline, not shortcuts, is what got this into production on that timeline. See our guide to realistic HubSpot integration timelines for how a project like this gets planned and sequenced.

When you do not need this level of build

Worth saying plainly: not every HubSpot integration needs a four-source pipeline with a control panel. If you have one source system with a clean connection and a shared identifier already in place, a native HubSpot connector or a single scheduled sync might solve your problem in an afternoon. Building this much infrastructure for one well-behaved source is overkill, and I would tell a client that directly rather than sell them a bigger build than they need.

This level of build earns its cost when you have multiple sources, no shared identifier, high record volume, or a compliance reason to trace every write back to its origin. If you are unsure which situation you are in, our HubSpot integration cost calculator is a faster way to get a scoped estimate than reading the rest of this article.

For teams that do need a custom build, our services page covers how engagements like this are scoped and delivered: pricing starts from $4,999 based on scope, with a 14-day money-back guarantee and a one-year bug warranty on top of standard Work Made for Hire terms. Every engagement runs under NDA, and invoicing is structured as IRS and IR35-safe B2B work.

For your engineer

The rest of this article is written for the person doing the technical work: your developer, your systems administrator, or whoever you bring in for the project.

Architecture overview: batch ingestion over HTTP. The pipeline pulls data in batches over HTTP rather than reacting to individual events. Batching smooths out traffic spikes from any one source and gives a natural checkpoint for retries when a source system times out mid-export. Each source system exposes an HTTP endpoint that returns records since the last successful pull. Nothing writes directly from a source system into HubSpot. Every record passes through the same pipeline stage, regardless of which of the four systems it came from, which matters because a bug fix in one path then applies to all of them instead of debugging four slightly different integrations. HubSpot enforces API rate limits based on your subscription tier, and a batch design respects those limits by default. See HubSpot's own documentation on API usage limits.

Normalizing raw records into HubSpot object types. Raw records rarely arrive shaped the way HubSpot expects: a scheduling system might send a date as a Unix timestamp, a billing system as a formatted string in a different timezone. Normalization converts every record into a consistent shape before mapping begins: dates to a single format, phone numbers to a single format, currency to a single denomination. This is where most sync bugs live, because a single malformed date field can silently fail an entire batch write without validation first. After normalization, each record maps to the correct HubSpot object type, contact, company, deal, ticket, or a custom object, depending on what the source represents. Records are written using the batch upsert endpoint, which creates or updates a record by a unique property value in a single call.

Upserts with full association handling. An upsert means the pipeline never has to ask "does this record already exist" before deciding how to write it. HubSpot either creates or updates based on a unique property value, which removes an entire class of race condition. The record also needs to land connected to the right company, deal, and parent ticket on the same write, not as a follow-up step: HubSpot's Associations API handles this. A two-step "create, then associate" pattern leaves a window where a record exists but is not yet connected to anything, and a sales rep who opens HubSpot during that window has no way to know the record is mid-sync. See our guide to HubSpot custom objects for how associations connect custom and standard objects.

Audit logging: every record traces back to its batch. Every ingestion cycle writes a log entry: which source, which batch, how many records, how many succeeded, how many failed and why. Every record written to HubSpot carries a reference back to the batch and the original payload that produced it, before normalization touched it. This makes the sync debuggable: when a record looks wrong, you start from "which batch wrote this and what did the source system actually send," not from grepping through application logs and hoping the relevant request is still there.

The sync control panel. The team running this integration day to day is not a group of engineers watching logs. The control panel gives them three things: pause ingestion per source, monitor pipeline health, and inspect individual records end to end. Pausing per source, rather than the whole pipeline, matters because the four systems do not fail together. Monitoring shows batch success rates and last-successful-sync timestamps per source, so a stalled feed is visible before it becomes a support ticket.

FAQ

How do you sync multiple systems into one HubSpot account without creating duplicate contacts?

You need a matching plan before you write any sync code, not after. Normalize every incoming record to a consistent format, then match against existing HubSpot records using a unique property value, and write with an upsert instead of a blind create. This is what stops the same customer from becoming three separate contacts because three source systems formatted their name differently.

What is a batch upsert and why use it over individual API calls?

A batch upsert creates or updates several records in a single API call, matched by a unique property value instead of a HubSpot record ID. It cuts the number of requests dramatically compared to one call per record, which keeps a sync further from HubSpot's rate limits and makes large syncs run faster and more predictably.

How fast can HubSpot leads sync from an external system?

In the Reevia build, leads reach HubSpot in under 50 seconds from the moment the source system generates them. Actual speed depends on batch frequency, normalization complexity, and how many connections each record needs on write. A near-real-time sync is achievable with the right batch cadence, even without a fully event-driven design.

Do I need custom objects for a multi-system HubSpot sync?

Not always. Standard objects (contacts, companies, deals, tickets) cover most cases. Custom objects make sense when a source system represents something HubSpot has no native equivalent for, like appointments or inventory items. Our guide to HubSpot custom objects covers when a custom object earns its cost versus when a standard object with extra fields does the job.

Next steps

If you are staring down a similar multi-source sync and want a second opinion on the plan before you commit budget, read the full Reevia HubSpot integration case study for the business context behind this build. For a scoped estimate on your own systems, run the HubSpot integration cost calculator, or see how engagements are structured on the HubSpot integrations services page.

I hold several HubSpot Academy certifications, including Data Integrations, Salesforce Integration, and Platform Consulting, and I have shipped 250+ projects across 17 years of engineering work, including production systems for bolttech and GigEasy. If you want to talk through your specific data sources before scoping anything, that conversation costs nothing.

Related Articles

All posts