All Docs
FeaturesNurtureHubUpdated March 21, 2026

Inside the CRM Sync Orchestrator: How NurtureHub Keeps Your Data Clean Across Every Integration

Inside the CRM Sync Orchestrator: How NurtureHub Keeps Your Data Clean Across Every Integration

Released in v1.0.57


Property agency data lives in a lot of places at once. Your CRM holds the authoritative contact record. NurtureHub holds the engagement history — who opened which email, their intent score, where they sit in a nurture sequence. In a busy lettings or estate agency, both sides of that picture are changing constantly, sometimes simultaneously.

v1.0.57 ships the CRM Sync Orchestrator: the engine that keeps those two worlds in sync without data loss, without duplicates, and without blowing through your CRM provider's API rate limits.

Here is how it works.


Delta Sync with Provider Cursors

Early sync implementations fetch everything every time. That works at low volume, but it doesn't scale — and it creates noise.

The Sync Orchestrator instead tracks a cursor for each connected CRM provider. A cursor is a lightweight bookmark (typically a timestamp or a sequence token, depending on what the provider exposes) that marks the end of the last successful sync window. On the next run, the orchestrator fetches only records that changed after that cursor.

The result: sync cycles stay fast even as your contact database grows, and each cycle touches only the data that actually needs attention.

Cursors are stored per-tenant, per-provider, so a slow sync on one integration never affects another.


Field-Level Conflict Resolution

Bidirectional sync creates a fundamental problem: what happens when the same field is updated in both the CRM and NurtureHub between two sync cycles?

The Sync Orchestrator resolves this at the field level using a clear, deterministic policy:

Data typeWinner
Contact data (name, email, phone, address, status)CRM
Engagement data (email opens/clicks, intent score, nurture sequence state)NurtureHub

This policy reflects where each system has genuine authority. Your CRM is the record of truth for who a contact is. NurtureHub is the record of truth for how that contact is engaging. Neither system blindly overwrites the other.

Conflicts detected and resolved are recorded in the sync audit log (see below).


Deduplication

Duplicate contacts are one of the most persistent pain points in any CRM integration. They arise from manual data entry, imports, API errors, and the edge cases that appear when two systems both try to create a record for the same person around the same time.

The Sync Orchestrator runs a multi-field matching strategy before creating any new contact record. If an incoming record matches an existing contact on a combination of identifiers, the orchestrator treats it as the same person and updates rather than creates. Duplicate suppression events are counted and logged per sync cycle.


Idempotent Upserts

All writes — in both directions — are idempotent. If a sync cycle is interrupted and re-run, or if the same data arrives twice, the end state is identical to running it once. There are no double-writes, no doubled engagement records, no phantom sequence enrolments.

This is particularly important during failure recovery. If a sync job fails halfway through, it can be safely retried from the beginning of the same cursor window without any manual cleanup.


Rate-Limited Outbound Batching

Different CRM providers enforce different API rate limits. Pushing a large batch of updates to a provider as a single burst is a reliable way to get throttled — or blocked.

The Sync Orchestrator batches outbound writes and spaces them to stay within each provider's documented limits. Batching is handled automatically; there is nothing to configure on a per-sync basis. The orchestrator knows the constraints for each supported provider (agentOS, Reapit, Alto, Street, Loop) and adapts accordingly.


Sync Audit Log

Every sync cycle produces a structured audit log entry. Each entry records:

  • Cursor window — the start and end of the time range processed
  • Record counts — contacts fetched inbound, records written outbound
  • Conflicts detected and resolved — with field-level detail
  • Duplicates suppressed — count of records matched to existing contacts rather than created
  • Errors — any provider API errors, with status codes and retry state

The audit log is accessible from the tenant admin area and is the first place to look when diagnosing an unexpected sync outcome.


Scheduled Execution via Inngest

The Sync Orchestrator runs as a scheduled Inngest function. Sync frequency is configured at the tenant level — different agencies can run on different intervals based on their volume and CRM plan.

Because the scheduling is managed by Inngest, intervals can be adjusted without any infrastructure changes. There is no cron job to edit and no deployment required to change a tenant's sync cadence.


What You Need to Do

Nothing. Existing CRM connections automatically pick up delta sync, conflict resolution, deduplication, and the audit log from the next scheduled sync cycle. No re-authorisation, no configuration changes, no disruption to live nurture sequences.


Summary

CapabilityWhat it does
Delta syncFetches only changed records using provider cursors
Conflict resolutionCRM wins on contact data; NurtureHub wins on engagement data
DeduplicationPrevents duplicate contact creation across sync cycles
Idempotent upsertsSafe to retry; no double-writes
Rate-limited batchingRespects per-provider API limits automatically
Audit logFull per-cycle record of conflicts, duplicates, and errors
Scheduled via InngestConfigurable sync interval per tenant, no infra changes needed