CRM sync scope
When you connect a CRM, sync doesn't start on its own. You get a chance to map fields and, if you want, narrow down which CRM contacts and leads come into the app before anything runs. This page covers both: starting sync, and the optional scope that limits what comes in.
Starting sync
A newly connected CRM sits in a Not started state — nothing is being pulled in yet. The reason for this is simple: your CRM's marketing lists aren't knowable until after you've connected, so there's no way to offer a scope up front, and starting a full sweep immediately would mean it's already too late to narrow it by the time you decide you want to.
- Connect your CRM (see Integrations and connectors if you haven't yet) and map your fields.
- Optionally, set up a scope — see below. You can also skip this and come back to it later; nothing syncs until you explicitly start it.
- Open the connection's details and, under Sync health, click Start sync. If you haven't finished mapping fields yet, this button is disabled with a tooltip explaining why.
Once started, sync runs continuously: an initial backfill pulls in everything currently in scope, and after that a regular poll picks up anything new or changed.
Choosing what syncs in
Under the connection's settings, in the Limit inbound sync section, you can optionally narrow which CRM contacts and leads sync into the app. This is entirely optional — leave it alone and everything syncs in, same as before.
This only ever affects what comes IN from your CRM. It has no effect on what goes OUT — see What scoping does and does not do below.
How you set a scope depends on your provider, because each one exposes list membership differently — this isn't a design choice on our end, it's what each CRM's API actually allows.
Dynamics and Pipedrive: pick a marketing list
For these two providers, Limit inbound sync shows the lists you've currently chosen as removable chips (in Pipedrive, "lists" are saved filters). Click Add lists to open a search box, type to find lists by name, tick the ones you want, and Add them — handy when a CRM holds dozens or hundreds of lists. Remove a list with the × on its chip. Only contacts/leads that are members of at least one chosen list sync in. Remove every list and sync goes back to unscoped (see "Changing the scope" for what a re-sync then does).
HubSpot: a contact property you create
HubSpot's search API has no way to filter by list membership at all — that's a real limitation of their API, not something we chose to leave out. So scoping in HubSpot works differently: you create a single-checkbox (boolean) contact property in HubSpot, and we filter on that property instead.
-
In HubSpot, go to Settings → Properties, choose the Contact object, and click Create property.
-
Set the Field type to Single checkbox (this makes it a boolean property).
-
Give it a label — the label can be anything you like (for example "Sync to app").
-
Before you save, check the internal name. HubSpot generates the internal name from the label automatically, and it's shown just below the label field as you type, usually as something like "Internal name:
your_label_here". Click it to edit it directly if it doesn't come out right. -
Set the internal name to exactly:
sync_to_thoughtfulyThis has to match exactly — no extra characters, no different casing, no
sync_to_thoughtfullywith an extra "l". A near-miss doesn't error. It just means the underlying search matches zero contacts, and sync silently imports nothing, with nothing in HubSpot or in our UI to tell you why. -
Save the property.
-
Back in the app, under Limit inbound sync, turn on Limit sync to contacts with the property checked, then save.
-
In HubSpot, tick that property on the contacts you want included.
We check the property's existence and type when you save the scope: if it's missing, or exists but isn't a boolean, saving is refused with a message naming the property so you know exactly what to go fix.
What scoping does and does not do
- Inbound only. A scope only limits what comes IN from your CRM. Everything you create or change in the app — new contacts, edits, anything — is still pushed OUT to your CRM regardless of scope. There's no separate "outbound scope"; scoping never holds anything back on that side.
- Deals are never scoped. Deals sync in as a read-only mirror in full, independent of any contact/lead scope you've set.
- New app-created contacts don't sync back in unless they're also in scope. If you create a contact in the app and it gets pushed to your CRM, that contact does not start syncing back down again unless it's also on a scoped list (Dynamics/Pipedrive) or has the scope property checked (HubSpot). Scope is scope in both directions of travel through the CRM — there's no built-in exception for records the app itself created.
Three things worth knowing before you turn this on
A contact that falls out of scope is kept, not deleted. If you narrow your scope and a contact no longer matches, we stop pulling updates for it — its existing data and its link to the CRM record stay exactly as they are. Nothing about scoping ever deletes a contact.
Contacts pushed to the CRM don't sync back unless they're also in scope. This is worth repeating because it surprises people: pushing a contact out to your CRM doesn't grant it a free pass back in. If it isn't on a scoped list or flagged with the property, it stays out of the inbound sync just like any other out-of-scope CRM record.
Only the lists you sync appear as connected segments. When you limit inbound sync to a set of CRM lists (Dynamics or Pipedrive), those are exactly the lists you can target as connected segments in a campaign — a list outside your scope isn't imported, so it doesn't show up as a segment to send to. If you later want to campaign to a list, add it to your sync scope and it will appear once the next sync brings its members in. (HubSpot scoping uses a contact property rather than lists, so all your HubSpot lists remain available as segments; only the flagged contacts within them are imported.)
Changing the scope
- Narrowing (removing a list, or turning the HubSpot flag off) takes effect automatically on the next poll. Nothing else to do.
- Widening (adding a list, or turning the HubSpot flag on) needs a manual Force re-sync. Here's why: our regular poll only asks your CRM for records changed since the last poll. A record that's sat unchanged in your CRM and was excluded under the old scope was never fetched at all — there's no "changed" event for the poll to notice, so it will never show up on its own no matter how long you wait. A Force re-sync re-pulls everything currently in scope from scratch, which is the only way those records come in.
- The app tells you when this applies: after any scope change, a banner reading "The sync scope changed. Records newly in scope haven't been imported yet" appears on the connection until you run a Force re-sync. You'll see this banner even after a narrowing-only change — running a re-sync then is harmless, just unnecessary.
- You can't change the scope while a sync is running — saving is refused until it finishes. This isn't arbitrary: an in-progress sync has page cursors from your CRM's API that encode the old filter. Changing the scope out from under a running page-walk would silently skip or duplicate records, so it's blocked instead until the current run completes.
Why Dynamics dynamic lists are greyed out
If you're on Dynamics, you'll notice some marketing lists appear in the picker greyed out, with a note that they're a dynamic list. This isn't a permissions problem — it's how Dynamics itself stores membership. A static list has real member rows we can filter on. A dynamic list's membership is a saved query with no rows at all, so there's nothing for our filter to traverse. Static lists work normally; dynamic lists can't back a scope no matter how they're configured, so we disable them in the picker rather than let you select one that would silently sync nothing.
FAQ
Q: Do I have to set a scope? A: No. It's entirely optional. Skip it and sync pulls in every contact and lead, same as before this feature existed.
Q: I set a scope but nothing is importing — why?
A: Check that your scope actually matches something. For a list scope, an
empty or deleted list matches nothing. For HubSpot, the most common cause
is the internal property name not matching sync_to_thoughtfuly exactly —
see the steps above for where HubSpot shows you the real internal name.
Q: Does scoping affect deals too? A: No. Deals always sync in full as a read-only mirror, regardless of any contact/lead scope.
Q: I widened my scope and ran Force re-sync — will it re-import contacts I already have? A: Yes, for everything currently in scope, not just the newly-added records. It's a full re-pull, not an incremental one. It re-applies your mapping and conflict policy the same way any Force re-sync does.
Q: Why can't I just pick a Dynamics dynamic list? A: Its membership is a saved query with no member rows in Dynamics itself — there's nothing there for our filter to traverse. See above.
Q: What permissions does my CRM connection need for this to work? A: See CRM permissions reference for the exact scopes/privileges per provider, and why a missing one usually fails silently instead of showing an error.