Skip to content

The integration that looked simple in the demo

  • Home
  • Blog
  • The integration that looked simple in the demo
The integration that looked simple in the demo

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.
Five stages a production CRM integration adds beyond the demoOrdered stages from data audit through field mapping, resilient sync, edge-case testing and monitoring, connected by arrows.What production adds to the demo1AuditdataFind dupes,missing fields2Map anddedupeDecide systemof record3Build authand syncOAuth, retries,idempotency4Test edgecasesEmpty email,long fields5Monitorand alertFailure logs,rate limits
The five stages a production CRM integration adds beyond the vendor demo: data audit, mapping and deduplication, resilient sync, edge-case testing and ongoing monitoring.

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.

Which CRM sync model fits which situationRows mapping each CRM sync approach to the workload it suits.Which sync model appliesOne-way batchLow volume, one system owns the record, nightly sync is enoughTwo-way real-timeBoth teams update records and conflicts must resolveMiddleware connectorStandard lead capture or contact sync, no unusual objectsCustom API codeUnusual schema, complex dedupe rules or internal systems
How the common CRM sync models map to workflow complexity, data volume and which team ends up maintaining the connector.

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.

  1. Audit the source data. Count duplicates, find empty required fields, and list every field type the CRM must accept. Do this before writing code.
  2. Define the system of record. For each field, decide which system wins when the two disagree. Document it in one page.
  3. Map fields explicitly. Never rely on default matching. Write the mapping down, including what happens to unknown or oversize values.
  4. Choose sync direction and cadence. Start one-way. Add real-time only if the workflow genuinely needs it.
  5. Build with retries and idempotency. Make every write safe to repeat, so a retry does not create a second contact.
  6. Test edge cases deliberately. Feed it messy records and watch what fails. Fix the handling before launch.
  7. 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.

First ninety days after a CRM integration go-liveMilestones and typical failure points in the first ninety days after launch.The first ninety days after go-live1Day 0OAuth live2Week 2First drop found3Week 4Duplicates appear4Day 60Team trusts data5Day 90Runbook in place
The milestones and typical failure points that appear in the first ninety days after a CRM integration goes live, from the first dropped event to a stable runbook.

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.

ApproachBest whenMain costWho maintains it
Native CSV importOne-off or occasional migrationManual effort per runAnyone on the team
Marketplace connectorStandard app-to-CRM syncSubscription and setupVendor plus your admin
Middleware (Zapier, Make)Multi-step workflows between common appsUsage-based fee and debuggingUsually a non-engineer
Custom code (REST API, webhooks)Unusual schema, internal systems, complex rulesEngineer time to build and runYour 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

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.

Frequently asked questions

  • Demos use clean, small datasets and a single user. Production brings large record volumes, custom fields, duplicate data, multi-user concurrency, and API rate limits. The failure mode is usually partial sync or silent data loss; you notice only when reports don't match. Verify with row-count reconciliation against the CRM before go-live.

  • Field types rarely match one-to-one. A text field in your app may map to a picklist or lookup in the CRM, and empty values can overwrite existing data. Write an explicit field map, handle nulls as "do not update", and test with a sample of real records, not demo data.

  • Start with the integration logs and CRM API response bodies. Most failures are 401 token expiry, 429 rate limiting, or 400 validation errors from a bad field value. Reproduce the failing record in a sandbox, then fix the payload. Turn on retries with backoff only after the root cause is fixed.

  • Confirm API access, OAuth scopes, and whether the CRM has a sandbox. Inventory the objects and fields you need, including custom ones. Check rate limits and webhook availability. Document how duplicates are matched. Skipping these turns a two-day demo into weeks of rework.

  • Reconcile counts between source and CRM for a known date range, then spot-check specific records. Set up alerts when sync lag exceeds a threshold or error rate rises. Keep an idempotency key per operation so retries don't create duplicates, and confirm that key is stored.

  • Store OAuth tokens encrypted and rotate them on schedule. Request the minimum scopes needed for the sync. Validate webhook signatures to block forged events. Log all data access and review it periodically. A leaked CRM token is a data breach, not just a sync problem.

  • Direct code gives control but you own retries, error queues, and API changes. Middleware like Zapier or Make handles those but adds per-operation cost and can become a bottleneck. For high-volume or complex mappings, custom code or a queue-based worker is usually more reliable long-term.

  • Duplicates usually mean the integration has no stable unique key. If the match uses name or email and those change, the system creates a new record instead of updating. Define an external ID field in the CRM and upsert on that key. Back up affected records before running a deduplication job.

  • CRM APIs cap requests per minute or day. When exceeded, you get HTTP 429 and sync stalls. Implement exponential backoff with jitter and queue requests. Monitor your remaining quota in logs. If volume regularly hits the cap, batch operations or move to the CRM's bulk API.

  • If the sync is low-volume, one-way, and mostly standard fields, a native connector or iPaaS is often enough. Export/import via CSV may be sufficient for monthly reporting. A custom integration pays off when you need real-time sync, custom objects, or strict control over data ownership.

0 comments

Be the first to share your thoughts.

Leave a comment

Chat on WhatsApp