A CRM integration is harder than expected the moment it leaves the demo, because production data is dirty and the sync breaks silently. The vendor showed a happy path with clean test records. Production hands you duplicates, custom fields, rate limits and expired tokens.
Key Takeaways
- Demos run on clean sample data; production data has duplicates, missing required fields and conflicting formats.
- The hard part is rarely the API call — it is field mapping, deduplication and deciding which system owns each record.
- One-way sync is an order of magnitude simpler than two-way sync; default to one-way unless two-way is genuinely required.
- Silent partial failures are the norm: a dropped webhook or expired token can stop updates for days before anyone notices.
- An integration needs a runbook, monitoring and a named owner after go-live; it is not a finish-and-forget task.
- Middleware or a native connector usually wins for standard needs; custom code is justified only when the schema or workflow is unusual.
What does a CRM integration actually involve in production?
A CRM integration connects your website, app or internal system to a customer database such as HubSpot, Salesforce, Zoho or Pipedrive so records move without manual re-entry. Production builds cover authentication, field mapping, duplicate detection, retries, error queues and monitoring — not one API call.
The work splits into three layers. The transport layer handles OAuth tokens, rate limits and webhook delivery. The mapping layer decides which field in your system corresponds to which field in the CRM, and what happens when one side is empty. The reconciliation layer handles duplicates, conflict resolution and the question of which system is the source of truth. A vendor demo typically shows only the transport layer working once, on tidy data, in a sandbox.
Our team has been burned by this enough times to say it plainly: the API is the easy part. The hard part is everything the demo skips.
Why does the demo look easy and the production build look hard?
Demos run against a clean sandbox with a handful of sample contacts, so every field maps first time and nothing conflicts. Production data defeats that in hours: duplicate records, missing required fields, custom fields the API does not expose by default, and teams who enter data in different formats.
The mechanism is simple but unforgiving. A demo record has a name, an email and a phone number that all match the CRM's expected types. A real record might have a phone number in a note field, two email addresses separated by a comma, and a country name the CRM's picklist does not recognise. Each mismatch either blocks the whole record or, worse, writes a mangled version and reports success.
There is also the volume problem. A demo syncs twenty records. Production syncs thousands, hits the vendor's rate limit, and then retries in a loop that makes things worse. If you are integrating a website with external software, plan for the mess before you write the connector.
When do you actually need a custom integration — and when is the simpler option right?
You need custom code when the CRM's native import, a marketplace connector or middleware such as Zapier or Make cannot model your workflow — unusual objects, complex deduplication rules, or data from an internal system. Standard lead capture and basic contact sync are usually fine with a native connector or middleware.
Be honest about the workflow before choosing. If a form submission just needs to become a contact, a native connector or a middleware step does it in an afternoon. If a customer portal must update an opportunity, a support ticket and a billing record in three different systems with a single source of truth, custom code earns its keep. The question is not whether custom is possible — it is whether the rules are unusual enough to justify an engineer on call.
This decision is the same shape as the buy versus build argument for the software itself: the more standard the workflow, the less you should build.
What breaks first when a CRM sync fails in production?
Authentication breaks first in most failures — an expired OAuth token, a rotated secret or a deactivated user account — and it fails silently for days because the error sits in a log nobody reads. Rate limits come next, then duplicate creation, then overwritten fields from a bad mapping.
Check in that order. First, look for a 401 or 403 in the integration's outbound calls; that means the token or scope is wrong. Second, look for 429 responses, which mean you are being throttled. Third, compare record counts on both sides: if the CRM has more contacts than your source system, duplicates are being created. Fourth, diff a sample of recently updated records against what your system last sent — a bad mapping overwrites clean data without an error.
A common mistake we see is treating a single failed webhook as harmless. One dropped event can leave the two systems permanently out of step, and the gap compounds every day.
What is the step-by-step sequence to scope and build one safely?
Front-load the data audit and field mapping, because those decisions change the code. The sequence below reduces rework: audit source data, define the system of record, map fields, choose sync direction, build with retries, test edge cases, then monitor.
- Audit the source data. Count duplicates, find empty required fields, and list every field type the CRM must accept. Do this before writing code.
- Define the system of record. For each field, decide which system wins when the two disagree. Document it in one page.
- Map fields explicitly. Never rely on default matching. Write the mapping down, including what happens to unknown or oversize values.
- Choose sync direction and cadence. Start one-way. Add real-time only if the workflow genuinely needs it.
- Build with retries and idempotency. Make every write safe to repeat, so a retry does not create a second contact.
- Test edge cases deliberately. Feed it messy records and watch what fails. Fix the handling before launch.
- Add monitoring and an owner. Alert on auth failures, rising error counts and record-count drift. Name the person who responds.
A small idempotency guard in the webhook handler saves more pain than almost any other line of code:
app.post('/webhook/crm', async (req, res) => {
const eventId = req.body.eventId;
if (await alreadyProcessed(eventId)) return res.status(200).end();
await upsertContact(req.body.contact);
await markProcessed(eventId);
res.status(200).end();
}); Which configuration decisions matter most before you build?
Three decisions shape everything that follows: which system is the system of record for each field, how duplicates are matched, and whether sync runs real-time or batch. Getting these wrong means rework after go-live, when production data is already flowing.
Duplicate matching is the subtlest. Match on email alone and you will merge two people who share an address. Match on email plus name and a legitimate rename splits one person into two. The correct key depends on your data, and you should test it against a real sample, not a synthetic one. Field ownership is equally political: sales wants the CRM to win, operations wants the internal system to win, and whoever loses will quietly stop trusting the data.
Real-time sync feels modern but it multiplies the failure surface. A batch job that runs every fifteen minutes is easier to pause, replay and debug. Choose real-time only when latency actually changes a business outcome — not because the dashboard looks better.
How do you verify it works beyond the happy-path demo?
Verify with deliberately messy records: a contact with no email, a duplicate that exists in both systems, a field longer than the CRM allows, and a webhook that arrives out of order. Confirm the integration retries, logs the failure and never silently drops a record.
Run a parallel check after launch. Pick a day, export the last fifty records from both systems, and diff them by hand. This catches mapping errors that monitoring misses. Check the vendor's API documentation — for example HubSpot's API documentation or Salesforce's API documentation — for the exact field limits and rate rules, because those vary between editions and change over time.
Then watch the first full week before you declare victory. Most silent failures appear in the first real business cycle, not in the test window.
What does it cost to operate — in engineer time, not licence fees?
The ongoing cost is engineer time for monitoring, field-mapping changes and failed-sync recovery — typically a few hours a month once stable, more in the first quarter. Cloud middleware adds a usage-based fee, but the dominant cost is the person who understands the mapping.
Cost drivers are the number of systems, the cadence, and the churn in your data model. Every time a field is added or renamed in one system, the mapping must be reviewed. Every new user who enters data differently increases the deduplication load. Licence costs for middleware scale with volume, but the expensive part is usually the rework when a rule was never written down.
If you are budgeting, do not ask only what the connector costs to build. Ask what a week of silently wrong data costs the sales team. That number usually dwarfs the build. A build quote breakdown should separate build effort from the first quarter of operational support, because the two are different work.
Security considerations when two systems share customer data
A CRM integration moves personal data between two systems, so you inherit both systems' access controls plus the integration's own credentials. Scope OAuth tokens tightly, encrypt secrets, log who changed what, and review exactly what the connector account can read.
Use a dedicated service account or OAuth app for the integration, never a personal login. If a person leaves and the integration ran under their account, the sync dies with their access — or worse, keeps running with permissions nobody has reviewed. Restrict the connector to the objects and fields it needs; a connector that can read every contact and delete records is a breach waiting for a leaked key.
Treat the integration's logs as security-relevant. They contain email addresses, names and sometimes phone numbers. Store them with the same care as the CRM data itself, and rotate secrets on a schedule, not after an incident.
A realistic scenario: the integration that "should have been a week"
A services company connects its booking form to its CRM so new enquiries become contacts automatically. The demo takes a day. Production takes three weeks: the form captures a phone number the CRM rejects, existing customers create duplicates, and nobody notices the sync stopped after a token expired.
The fix was not a better API client. It was a half-day data audit that found twelve distinct phone formats, a deduplication rule based on email plus phone, and a monitoring alert on record-count drift. The build itself was two days. The other two and a half weeks were spent discovering the rules that should have been written down before the first line of code.
That pattern repeats constantly. The integration looks simple because the demo hides the data. When our team scopes a custom software development job that includes a CRM connector, the first deliverable is the mapping and ownership document — not the code.
Alternatives compared
Choose between native import, middleware, a marketplace connector and custom code by matching workflow complexity, data volume and who will maintain it. The table below summarises the trade-offs; the simpler option is right more often than vendors admit.
| Approach | Best when | Main cost | Who maintains it |
|---|---|---|---|
| Native CSV import | One-off or occasional migration | Manual effort per run | Anyone on the team |
| Marketplace connector | Standard app-to-CRM sync | Subscription and setup | Vendor plus your admin |
| Middleware (Zapier, Make) | Multi-step workflows between common apps | Usage-based fee and debugging | Usually a non-engineer |
| Custom code (REST API, webhooks) | Unusual schema, internal systems, complex rules | Engineer time to build and run | Your development team |
The table is a decision aid, not a ranking. A small team with a standard lead form should almost never write custom code. A company with a bespoke internal system and strict deduplication rules should almost never rely on a generic connector. The middle ground — middleware — covers more of the space than either vendor wants you to believe.
In short: the demo hides the data, and the data is the project. Audit first, map explicitly, default to one-way sync, build idempotency and monitoring in from day one, and name an owner. The integration that survives production is the one whose rules were written down before the connector was built.
People also search for
- What is involved in website and software integration?
- Should we buy off-the-shelf software or build custom?
- How much does a CRM integration cost to build?
- Does hosting affect how an integration performs?
- How does app platform choice affect CRM integration?
- More articles on integration and build decisions
If a CRM integration has already burned a sprint or two on your side, our team can help you audit the data, pin down the mapping and build something your own developers can operate. Start with a review through our contact page, or see the range of work we handle under our services.












0 comments
Be the first to share your thoughts.
Leave a comment
Replying to — cancel