On this page
- What CRM integration actually is
- Who it is for, and who it is not for
- What we actually build
- How it works technically
- Field custody, the rule that prevents most sync disasters
- The build process stage by stage
- What you get at handover
- Where CRM integrations go wrong
- What it costs to run once live
- How to tell whether you need this
- How to start
What CRM integration actually is
CRM integration is the work of making your CRM agree with the other systems that hold the same facts: the product database, the billing system, the support desk, the marketing platform. Done properly it is not a pipe between two apps. It is a written decision about which system owns each field, a sync that applies changes idempotently in that direction, a log of every conflict, and a scheduled reconciliation that checks both sides still match. The connector is the easy part. The ownership decisions are the project.
Most CRMs die the same way. Three systems write to the same field, nobody agreed who should, and after a few months the sales team stops trusting the record and keeps the real state in a spreadsheet. At that point the CRM is a place data goes to be forgotten, and no amount of new tooling fixes it, because the problem is not connectivity. It is that nothing decides what is true.
So the first deliverable is never code. It is a field-level map naming one writer per field, with the exceptions listed and a survivorship rule attached to each. Once that document exists, the engineering is mostly mechanical.
- One writerEvery field names exactly one system permitted to write it. Everything else reads. Fields with two writers are the source of most sync incidents.
- Natural keysRecords match on a normalised real-world key, a lowercased email or a cleaned company domain, not on a record id that only one system understands.
- Conflicts loggedWhen a survivorship rule fires, both values, the rule and the winner are recorded. That log is how you discover the rule is wrong.
- Reconciled nightlyA scheduled job compares both systems field by field and opens a ticket on drift, because a sync that has silently stopped looks exactly like a sync with nothing to do.
Who it is for, and who it is not for
This is for companies where the CRM is one of several systems holding customer state, and where the same fact is currently entered by hand in more than one place. If your CRM is the only system and a native connector covers your two other tools, buy the connector.
| Your situation | Verdict | Why |
|---|---|---|
| A CRM plus billing, product and support all holding customer state | Good fit | Four systems means twelve possible pairings. Ownership has to be declared or it will be improvised. |
| Someone re-keys the same field into two systems every week | Good fit | That is a mapping and a trigger, and re-keying is where the divergence starts. |
| Native connector already covers your two tools and nobody complains | Not a fit | Buy the connector. Custom work here is expensive and adds a thing to maintain. |
| You are about to change CRM | Wait | Build the integration against the CRM you are keeping, not the one you are leaving. |
| Records are already duplicated and nobody knows the real count | Fix first | Syncing on top of duplicates multiplies them. Dedupe is a separate project and it comes first. |
| You want the integration to clean bad data on the way through | Careful | Normalisation yes, invention no. A sync that guesses missing values makes the data worse and harder to audit. |
Three things that have to exist before the build
- An agreed natural key per object. Usually a lowercased email for people and a normalised domain for companies, with the known exceptions written down: shared inboxes, subsidiaries, personal addresses on business accounts.
- API access at a tier with enough call allowance, plus somebody who can raise it. Integrations that work in testing and fail in production are usually hitting a ceiling nobody checked.
- A named owner for the CRM schema. If anyone in the company can add a required field or a validation rule on a Tuesday afternoon, the integration will break on a Tuesday afternoon.
Who should not buy this
- Teams whose real problem is CRM adoption. If sales will not update the record, syncing more data into it changes nothing.
- Anyone hoping the integration will settle an argument about which department owns the customer. It will surface the argument, not resolve it.
- Companies mid-way through a data migration. Finish the migration, then integrate the result.
- Teams who need reporting rather than sync. That is a warehouse job, and building it as an integration makes it slower and more fragile.
What we actually build
Six components. Most of this build contains no model at all, which is worth saying plainly on a page hosted by an AI automation studio.
The field custody manifest
A version-controlled file listing every object and field in scope with its writer, its readers, its transform, its allowed values and its conflict rule. It is readable by an operations lead, it is the artefact you argue about, and it is what the sync compiles from. When it changes, the change goes through review like any other code.
The identity and dedupe layer
Normalisation and matching before anything writes. Emails lowercased and trimmed, domains stripped of subdomains and free-mail providers flagged, company names normalised for matching but never overwritten. Deterministic rules first. Fuzzy matching only with a confidence threshold and a review queue, because an automatic merge of two real customers is one of the few integration errors that is genuinely hard to undo.
The sync workers
One worker per direction, driven by webhooks where the platform offers them and by a polled watermark where it does not. Each write is an upsert on the natural key, carries an idempotency key, and is tagged with its source so that the echo event coming back does not start a loop. Batched where the API rewards batching, serialised per record so two updates to the same contact cannot race.
The conflict log and the review queue
Every time a survivorship rule fires, the system records both values, the rule applied, the winner and the source events. Anything the rules cannot settle goes to a queue a human clears. Teams often discover their real ownership policy by reading a fortnight of that log, which is a better outcome than the workshop that was supposed to produce it.
The reconciliation job
Nightly, it walks both systems and compares the fields in scope. Drift opens a ticket with the record ids attached. This is the component that catches the failure everyone misses: a sync that stopped days ago and produced no errors, because zero events processed looks identical to a quiet weekend.
The backfill, run separately
History moves through its own path, with its own rate limit budget, its own batch size and a resumable cursor. Running a backfill through the live path is how teams consume a day's API allowance by lunchtime.
Start with the native connector and note every time it forces a compromise: a field it cannot map, a direction it cannot express, a conflict it resolved wrongly. After a month you have a specification written from evidence rather than from a whiteboard, and you may find the connector was fine.
How it works technically
Events in, identity resolved, custody applied, write attempted, result verified, drift reconciled. The parts that break in production are identity, loops and rate limits, in that order.
Triggers, watermarks and the ordering problem
Webhooks are cheaper and faster, and they are not reliable enough to be the only path: they can be delayed, duplicated or dropped. Every webhook-driven sync also needs a polled sweep on a watermark to catch what was missed. Advance the watermark only after the write has been confirmed, never before, because the crash between those two lines is the classic silent data loss. Ordering matters too, since two updates to the same record arriving out of order will leave the older value in place. Serialise per record key rather than globally. The trade-offs are covered in webhooks vs polling.
Writes, echoes and loops
A two-way sync without loop suppression is a machine for generating infinite updates. System A writes, the webhook fires, system B writes back, A hears its own change and writes again. Three defences, and you want all three: tag every write with its source and ignore inbound events carrying your own tag, compare the new value with the current value and skip no-op writes, and cap updates per record per hour so a loop trips a circuit breaker instead of running all night.
Rate limits and the CRM's own automation
CRM APIs meter calls, and the allowance depends on your product tier, so read your own limits page rather than any blog. Budget calls per record before you build: a lookup, a dedupe check and a write is three calls, and a fifty-thousand record backfill is a hundred and fifty thousand of them. A write into a CRM can also fire the CRM's own workflows. A backfill touching a field watched by an email automation is how a company sends a very large number of unintended emails in one afternoon.
# contact.custody.yaml
# One writer per field. Everything else reads. Direction is per field, never per object.
object: contact
natural_key: email_lower # the dedupe key, deliberately not the CRM record id
sync:
trigger: webhook # poll only where webhooks do not exist
poll_fallback_minutes: 15
batch_max: 200
loop_suppression: source_tag # ignore an inbound event this system caused
idempotency_key: "sha256(object + natural_key + field + new_value + source_event_id)"
fields:
email:
writer: product_db
readers: [crm, billing, support]
transform: lower_trim
pii: true
lifecycle_stage:
writer: crm
readers: [product_db, marketing]
allowed_values: [lead, mql, sql, customer, churned]
on_invalid: reject_and_log # never coerce a value you do not recognise
plan_tier:
writer: billing
readers: [crm, support]
last_active_at:
writer: product_db
readers: [crm]
write_if: "new_value > current_value" # monotonic, never moves backwards
owner_id:
writer: crm
readers: [support]
survivorship: newest_non_empty
on_conflict: log_both_values
deletes:
strategy: tombstone # propagate a delete, never a silent no-op
merges: follow_surviving_id # CRM merges must repoint foreign keys
dead_letter:
queue: crm_sync_dlq
retry: { attempts: 5, backoff: exponential, jitter: true }
alert_after: 10
reconciliation:
schedule: "daily 02:00"
compare: [email, lifecycle_stage, plan_tier, owner_id]
tolerance: 0
on_drift: open_ticketTwo lines in that file are worth more than the rest combined. The write_if guard on last_active_at makes the field monotonic, so an out-of-order event cannot move a timestamp backwards. The on_invalid: reject_and_log on the picklist means an unrecognised value is refused loudly rather than coerced into the nearest match, which is how bad data enters a CRM and stays there.
- Upsert
- A write that creates the record when the key matches nothing and updates it when it does. Upserts are only safe against a natural key. Upserting on a system-specific id creates the same person twice.
- Natural key
- The field or combination that identifies a real entity across systems, such as a lowercased email or a normalised company domain. Weak natural keys are the direct cause of duplicate records.
- Survivorship rule
- The stated rule deciding which value wins when two systems have written the same field. Common rules are newest timestamp wins, non-empty wins, and human edit beats machine write.
- Watermark
- The stored timestamp or cursor recording how far a sync has read, so the next run resumes instead of rescanning. A watermark advanced before the write is confirmed causes silent data loss.
- Tombstone
- A record marking that something was deleted, kept so the deletion can propagate to other systems. Without tombstones, deletes vanish and a deleted contact reappears on the next sync.
Field custody, the rule that prevents most sync disasters
Almost every integration incident we have been called into traces back to a field with two writers and no stated rule. The model below is not sophisticated. It is just written down, which is the part everybody skips.
The ChatGPTalker Field Custody Model
Five rules covering who may write what, and what happens when the answer is contested. Applied field by field, in a file, before any connector is configured.
Every field names exactly one system permitted to write it. Everything else reads. A field with two writers is not a design, it is a bug with a date on it.
The same contact can have the CRM owning stage and owner, billing owning plan tier, and the product database owning last active date. Object-level two-way sync is where the trouble starts.
Where two systems genuinely must write, state the rule: newest wins, non-empty wins, or human edit wins. Put it in the manifest rather than in the memory of whoever configured it.
Record both values, the rule applied, the winner and the source events. A fortnight of that log tells you more about your real data policy than any workshop will.
Fields accrete. Quarterly, flag any field nothing has read in ninety days. An unused field still costs a mapping, a sync call and a possible conflict, and it still holds personal data you must delete on request.
When a vendor says two-way sync, ask which system wins on a specific contested field, and what happens to the losing value. If the answer is last write wins, the design is that whichever system was slowest to fire is right, which is not a policy anyone would choose deliberately.
The build process stage by stage
Six stages. The first is a data audit, and it is the stage clients most often want to skip and most often thank us for afterwards.
- Field-level data audit
Every object and field in scope profiled: fill rate, distinct values, duplicate rate on the proposed natural key, and which system last wrote each field. This is where you find out that a third of your company records share four generic domains.
- The custody manifest
The map gets written and argued about with the people who own each system. Contested fields are the useful part of the meeting. The output is a file, in the repository, with a name attached to every decision.
- Identity and dedupe
Normalisation, matching rules, a duplicate report and, where needed, a merge plan run by humans with the machine proposing. Nothing syncs until the duplicate rate on the natural key is understood and accepted.
- One field, end to end
A single low-risk field synced through the full path: trigger, worker, idempotent write, verification, conflict log, reconciliation. Every architectural mistake shows up here, cheaply, on a field nobody would miss.
- Widen the scope, then backfill
Remaining fields added in batches, each with its custody entry. The backfill runs last, on its own path, in off-peak windows, with the CRM's own workflow automations reviewed and paused where a bulk write would trigger them.
- Reconciliation, alerting and handover
The nightly comparison goes live, the dead letter queue gets an owner, and heartbeat alerts fire when a sync produces no events for longer than it should. Then documentation and a walkthrough with the person who will own it.
A CRM write can fire workflows, notifications and email sequences that were designed for human activity. Before a bulk write, list every automation watching the fields you are about to touch, and pause them deliberately. This is the single most expensive mistake in this category and it takes twenty minutes to prevent.
What you get at handover
The manifest, the workers, the queues and the reconciliation all run in your infrastructure under your credentials. The test of a real handover is whether your team can add a new field to the sync without calling us.
We also hand over the document nobody asks for: what the integration deliberately does not do, and why. Six months later that page prevents an argument about whether something was forgotten or decided.
Where CRM integrations go wrong
Six failure modes. Every one of them is recoverable if you find it in week one and unpleasant if you find it in month six.
The ping-pong loop
Two-way sync with no loop suppression. A writes, B hears it and writes back, A hears its own echo. The record updates forever, the audit trail fills with machine edits, and the API allowance disappears. Source tagging, no-op comparison and a per-record update ceiling are the three defences.
Duplicate explosion from a weak key
Syncing on a system-specific record id, or on an email address for a population that shares inboxes, produces a second copy of everyone. The copies then sync onward. Profile the duplicate rate on your proposed natural key before writing a line of sync code.
The backfill that eats the day's quota
History pushed through the live path consumes the API allowance, live events queue up behind it, and by afternoon the sync is hours behind with no error to show for it. Separate path, separate budget, off-peak window, resumable cursor.
Deletes and merges that go nowhere
Most integrations sync creates and updates and quietly ignore deletions and merges. CRM users merge records constantly. When they do, the other system still points at an id that no longer exists, and the next sync recreates the record you just merged away. Handle tombstones and surviving ids explicitly.
Writes that succeed and change nothing
The API returns 200. The record is unchanged, because a validation rule rejected the field, or field-level permissions on the integration user exclude it, or a workflow overwrote your value a second later. Verify after write on a sample, and reconcile nightly, or you will trust a green log that describes nothing.
Personal data spreading faster than the policy
Each new destination is another place a deletion request has to reach. Mark personal fields in the manifest, keep the list of destinations current, and make deletion a first-class sync operation rather than a manual sweep somebody performs under time pressure. More detail in personal data in AI pipelines.
The most common way a CRM integration fails is by stopping. No exceptions are thrown, no alerts fire, the dashboard is green, and the data quietly diverges for three weeks. Alert on the absence of expected events and reconcile on a schedule, because a healthy silent sync and a dead one look identical from the outside.
What it costs to run once live
Three real cost lines, and a fourth that is usually zero. Most CRM integration work is deterministic, so there may be no model in the running system at all.
| Cost line | What drives it | How it scales |
|---|---|---|
| Infrastructure | Queue, workers, a small database for the conflict log and watermarks. | With event volume. Modest for most companies until you pass millions of records. |
| CRM API tier | Call allowance, which varies by product and tier. Heavy sync can push you to a higher plan. | With records changed per day multiplied by calls per record. |
| Maintenance | Schema changes, API version sunsets, new fields, new systems joining the sync. | With the number of connected systems and how freely people edit the CRM schema. |
| Model tokens | Only if a model handles fuzzy entity resolution or free-text normalisation. Often zero. | With the volume of records that deterministic rules could not match. |
The number worth estimating before you commit is API calls, because that is the ceiling you hit first. Count calls per record honestly: a lookup, a dedupe check and a write is three, and any enrichment adds more. Put your own allowance in the box below, taken from your CRM's current limits documentation for your tier rather than from an article.
Enter your CRM's documented daily allowance for your tier. The peak figure assumes a fifth of the day's volume lands in the busiest hour, which is normal for business-hours systems.
Run it with backfill volumes too. A one-off load of half a million historical records at three calls each is one and a half million calls, which is why the backfill gets its own path and its own window. The connective layer underneath is shared with systems integration, so if you are building several of these it is worth building the queue once.
Before adding a field, ask which system reads it and what decision changes because of it. Roughly a third of the fields on a typical wish list have no reader. Cutting them removes calls, conflicts, maintenance and personal data exposure at the same time.
How to tell whether you need this
The signal is not the number of tools. It is whether the same fact exists in two systems with no stated rule about which one is right, and whether anybody has stopped trusting the CRM because of it.
If you ticked one or two, the fix is probably a written ownership map and an afternoon of configuration, not a build. Write the map anyway. It costs nothing and it is the deliverable that makes the eventual build cheap. Teams whose next step is pipeline hygiene rather than sync should look at sales pipeline automation instead.
Profile fill rates, duplicate rate on your natural key and last-writer per field. It takes a day with an export and some SQL, and most teams find one field being written by three systems.
How to start
Read access to both systems and one week is enough to tell you whether this is a mapping problem, a duplicate problem or an adoption problem. The three have very different price tags and only one of them is an integration.
- Send the list of systems, the objects that exist in more than one, and the fields people currently re-key by hand.
- We profile the data, propose the natural keys, measure the duplicate rate and draft the custody manifest for the contested fields.
- You get a scoped build with stages and a cost, or a recommendation to configure the connector you already own and stop there.
- If it proceeds, one low-risk field goes end to end first, so the architecture is proved on something nobody would miss.
The mechanics that keep this reliable overnight are covered in idempotency in automation, which is worth reading before you evaluate any vendor in this category.
ChatGPTalker. CRM Integration: Sync, Field Custody and Conflict Rules. chatgptalker.com/services/crm-integration/