xMatix
Sign in Request demo
xMatix
PRODUCTS
SalesField Sales & SFACRMRewardsClaimsInventoryProcurementWarehouse ManagementField ServiceServiceSupportTelephony & MessagingFinance & AccountingPayrollExpense ManagementCommercePortalsAnalytics & ReportingData StudioMobile AppSee all products →
PLATFORM
Platform overviewApp BuilderAutomationIntegrationsSecurity & GovernanceChange ManagementDevelopers
SENSE AI
Sense AI overviewSense AssistSense ControlSense VisionAI StudioTrust & governanceIn Claude & ChatGPTUse cases
SOLUTIONS
Auto DMSConsumer Goods DMSSales Force Automation (SFA) FMCG & DistributionManufacturing & Dealer NetworksAutomotive & DealershipsPharma & HealthcareConsumer DurablesAgri-InputsBuilding MaterialsService NetworksWarehousing & 3PLFinancial AccountingERP SoftwareIndia GST ComplianceUAE VAT & e-InvoicingSaudi ZATCA & VATAll solutions →
RESOURCES
Knowledge CenterDeveloper & CLIBlogGuidesWhat is xMatix?Company facts
COMPANY
AboutCareersPartnersEventsContactAuthorsLegal
Sign in Request demo
Home/Docs/Integrations/Set up a scheduled sync
HOW-TO · Last reviewed

Set up a scheduled sync

A sync profile is standing configuration that keeps chosen xMatix entities in step with one external system on a schedule. You declare the entities, the direction for each and their field mappings; the profile then compiles into the integration flows that do the work, on the integration app it belongs to. You set it up after the integration app and its connection exist, and once it runs you watch it on the Sync Monitor.

This is a different thing from a mobile sync profile, which governs offline data on devices. The two share a word, not a mechanism.

Overview

You build and run a profile from Setup → Platform → Sync profiles. The list shows every profile with its System, Status, Schedule ("Manual only" when it has none), Entities, Flows, Conflicts, Watermark lag and Last cycle. Above the list are the counters Profiles, Active, Open conflicts, Parked records and Falling behind. Each row has Compile and Open.

Opening a profile shows its header — Status, External system, Integration app, Connection, Schedule, Default conflict policy, Overlap window and Runs as (the sync identity), plus the counters Entities, Field maps, Ledger rows, Open conflicts and Worst watermark lag. Below it are these tabs:

TabWhat you do there
EntitiesDeclare which xMatix entities sync with which external objects, in which direction and order.
MappingPair fields for the entity chosen in the picker; add mappings by hand or with Discover fields.
ScheduleSet the cron schedule, overlap window, status and nightly reconciliation.
Sites, Outbound queuePush providers only (Tally): the registered client sites and the queue they collect from.
CyclesThe cycle history table (see the note under Step 7).
ReconciliationResults of the nightly reconciliation runs, with Reconcile now.
ConflictsThis profile's conflicts inbox — the same one the Sync Monitor shows.
RecordsThe ledger: one row per paired record, with its status, last error and Resume.
SettingsName, default conflict policy, sync identity and the Active switch.

The header also carries Compile and Reseed all on every tab. When the flows a profile is running no longer match what it declares, a warning above the tabs says how many flows "are running an older compiled version", lists them, and offers Compile now.

When to use it

  • You want the same records kept up to date on both sides over time, not moved once. For a one-off load, use import instead.
  • You want xMatix to take a steady feed from a system of record (inbound), push its own records out (outbound), or both (bidirectional) with conflict detection.
  • You want changes to land within minutes on a timetable. For pushing an xMatix change out the moment it happens, an entity-event flow is the right tool.

The external systems you can choose are the registered sync providers: Salesforce, Zoho Books, Zoho Payroll, Zoho People and Tally.

How xMatix handles it

Compile turns the declaration into flows. Saving an entity or a mapping only edits the declaration; nothing runs differently until you compile. Compiling writes a new flow version only where the generated flow changed, so an unchanged compile writes nothing, and it never moves watermarks or run history. If the declaration has errors, nothing is compiled and you see the errors.

Compile also arms or disarms the schedule. Each generated flow gets a schedule trigger that copies the profile's Schedule. Compile switches that trigger on only when the profile's Status is Active and its Active switch is on; otherwise it switches it off. Changing Status or the Active switch on its own does not touch the triggers, and the running flows do not check the profile's status. So every change of Status, Active or Schedule needs a compile to take effect.

A trigger you edit keeps your schedule. If someone changes a generated flow's schedule on the integration app, later compiles leave that trigger alone and warn that it "kept their own schedule instead of the profile's". To make it follow the profile again, set it back to the schedule the profile last gave it.

Each pass reads only what changed. Each entity keeps a cursor (a watermark) per direction. On every pass the engine reads what changed since the cursor, minus the Overlap window (default 120 seconds), which absorbs clock differences between the two systems. Re-reading is cheap because unchanged records are dropped as echoes.

The ledger pairs records. Each synced record has a ledger row linking the xMatix record to its external key, so a record is updated rather than created again. A hash of the mapped fields is stored at each successful sync. A record that comes back unchanged, including the engine's own write echoing back, matches the hash and is dropped.

Conflicts follow a policy. When both sides changed the same field since the last sync, the entity's conflict policy decides (see Configuration). Field-level merge opens a conflict listing only the contested fields; fields only one side changed still move.

Ranks order the writes. Entities run in ascending Execution rank; equal ranks run together. A parent must be written before the child that points at it. Apply derived ranks works the ranks out from the references between entities. Entities that point at each other share a rank and settle over two cycles.

The identity bounds the sync. The engine reads and writes xMatix as the sync identity user, so record-level security limits what it can see and change. A profile can never sync more than that user can.

Some entities cannot be synced at all. Entities that the platform's own engines write (for example the posted ledger, derived balances and security configuration) are refused in every direction when you add them.

Prerequisites

  • The Manage integrations setup capability. It gates the Sync profiles screen and every sync-profile action.
  • An integration app with a working connection to the external system. The profile uses that app's connection and secrets, and its runs appear in that app's run history. If the app is switched off, none of the profile's flows run.
  • A dedicated xMatix user to act as the sync identity, with access to every record the sync should read or write. You enter it by its user id.
  • For outbound or bidirectional entities on Salesforce: a field on the external object that holds the xMatix id and is marked External Id and Unique there (the keyed-upsert field).
  • In a sandbox: schedules do not fire unless the integration app allows sandbox execution.

Procedure

An earlier capture of the New sync profile dialog, with fields for Name, Integration app, Connection, External system, Sync identity and Schedule

Step 1 — Start the profile

Go to Setup → Platform → Sync profiles. There are two ways to start:

  • Start from template (recommended). Pick a Starter template for your external system. The dialog lists the template's entities in groups, with the recommended ones ticked and a direction for each from the template's allowed list. If no profile for that system exists yet, it also asks for Profile name, Integration app and Connection (leave either empty to have the template create them) and the Sync identity user id. Fill in any Parameters the template asks for, leave Run field discovery for entities the template marks ticked if the connection already works, and select Create profile. The result lists each entity as Created, Updated, Unchanged, Dependency or Skipped, plus warnings and next steps. There is one profile per external system: applying a template again extends that profile and never overwrites your edits.
  • New blank profile. In the New sync profile dialog, enter Name, choose the External system, then the Integration app and one of its Connections (the connection list unlocks once an app is chosen). Enter the Sync identity (user id) and, optionally, a Schedule (6-field cron, UTC). Read any Provider capabilities note that appears. Select Create.

Either way the profile is created in Draft, and nothing runs yet. A blank profile opens on its detail page.

Step 2 — Declare the entities

On the Entities tab, select Add entity. Choose the xMatix entity (entities already in the profile are shown but cannot be picked again) and the External object — a list read live from the connection, or a text box if the schema cannot be read. Set the Direction. Leave Delete propagation at None unless you have decided deletes should travel. Select Add; the entity is saved and you are reminded to compile.

When the entities are in, select Apply derived ranks. The confirmation lists each rank change and any entities in a reference cycle; select Apply ranks. To add entities a template offers later, use Apply template on this tab.

Step 3 — Map the fields

Open the Mapping tab and choose the entity in the picker (or use Field mapping on the entity's row). Select Discover fields to read the external object and propose matches. Exact and Likely matches are ticked; a Possible match is a guess, so read its Why before ticking it. Show N unmapped field(s) explains every field that was not proposed. The dialog also tells you whether a keyed-upsert field was found; applying adopts it for the entity. Select Apply N mapping(s) to save the ticked mappings. Applying again updates rather than duplicates.

For anything discovery could not match, select Add mapping and fill in the fields described under Fields. Fields that can never be mapped are shown as "cannot be mapped" and cannot be picked.

Step 4 — Compile

Select Compile in the page header and confirm. You see one of three outcomes:

  • a toast "Compiled: N new version(s), N unchanged" — the flows are built;
  • Compiled with N warning(s) — the flows are built, but read every warning;
  • The declaration is not valid, so nothing was compiled — fix each listed error at its source, then compile again.

Step 5 — Set the schedule and status

On the Schedule tab, select Edit. Enter the Schedule (6-field cron, UTC) — six fields, seconds first, so 0 */15 * * * * is every 15 minutes. Work out the UTC time for any fixed time of day. Check the Overlap window (seconds). Set Status to Active and select Save. Because this starts writing to a live system, you are asked to confirm with Activate.

On the Settings tab, check that the Active switch is on (it is on for every new profile).

Step 6 — Compile again to arm the schedule

Select Compile again. This is the step that switches the schedule triggers on, because compile reads the status you just saved. Without it, an Active profile with a schedule does not run.

Step 7 — Watch the first cycles

After the first scheduled time has passed:

  • On Entities, the Cursor lag column shows a lag per direction instead of "No cursor yet".
  • On Records, paired records appear. Filter by entity or status, or search by an xMatix record id or an external key. Look for Error, Conflict and Deferred rows and read Last error.
  • In the integration app's run history, the profile's flows show their runs and any failed step.
  • On the Sync Monitor, the profile's health and conflicts appear alongside the others.

The Cycles tab, the Last cycle column and the cycle counters are not currently recorded, so they stay empty even when the profile is syncing. Use the cursors, records and run history instead.

Step 8 — Pause or stop a profile

To pause, open Schedule → Edit, set Status to Paused, select Save, then Compile. The compile switches the triggers off. Alternatively turn Active off on Settings and compile. Configuration, watermarks and history are kept, so you can resume by setting Active again and compiling.

Clearing the Schedule box does not currently make a profile manual-only: the saved schedule stays as it was. Reopen the Schedule tab after saving to check. To stop the schedule, pause the profile as described above.

Step 9 — Remove an entity

To stop syncing an entity but keep its record pairing, select Edit on its row and make it inactive. To remove it entirely, select Remove. If the entity has paired records, a second confirmation explains that discarding the ledger means the next pass re-pairs everything from scratch and may create duplicates. Select Discard the pairing and remove only if you accept that. Nothing is deleted in xMatix or in the external system either way.

Fields

New sync profile dialog

FieldWhat it meansNotes
NameThe profile's name, used in lists and in the names of its flows.Required; must be unique across the tenant's profiles.
External systemThe sync provider: Salesforce, Zoho Books, Zoho Payroll, Zoho People or Tally.Required. A Provider capabilities note explains what the provider lacks — keyed upsert, a change watermark or a delete feed.
Integration appThe app whose connection, secrets, access and run history the profile uses.Required.
ConnectionA connection that belongs to the chosen app.Required; must belong to that app.
Sync identity (user id)The xMatix user id the engine reads and writes as.Required. There is no user picker; paste the id. The header shows the user's name as Runs as.
Schedule (6-field cron, UTC)When cycles run.Optional; blank means manual only. A five-field expression is refused, with a hint to add a leading seconds field.

Schedule tab

FieldWhat it meansNotes
Schedule (6-field cron, UTC)The cycle schedule for every entity; a cycle walks the ranks in order.Takes effect at the next compile.
Overlap window (seconds)How far each pass rewinds its watermark to absorb clock skew.Required; 0–3600; default 120.
StatusDraft, Seeding, Active, Paused or Failed.Set by you only; nothing changes it automatically. Only Active lets compile switch the schedule on.
Nightly reconciliation (6-field cron, UTC)When the daily reconciliation runs.Blank turns it off. Takes effect at the next compile, which creates the Reconcile flow.
Reconcile window (hours)How far back each reconciliation looks.Required; 1–336; default 26.
Auto-repairHands missing or stale records back for the next catch-up to re-read.Bulk Salesforce entities only; Zoho differences are reported for a reseed.

Settings tab

FieldWhat it meansNotes
NameThe profile name.Required.
Default conflict policyThe policy for every entity that does not set its own.Default Field-level merge.
Sync identity (user id)The user the engine runs as.Changing it asks you to confirm: a narrower identity silently stops syncing records it cannot read.
ActiveWhether the profile may be scheduled.Inactive keeps configuration, watermarks and history. Takes effect at the next compile.

Add entity dialog

FieldWhat it meansNotes
xMatix entityThe entity to sync.Required. Cannot be changed after adding; remove and re-add instead.
External objectThe external object or table it is kept in step with.Required.
DirectionInbound (external to xMatix), Outbound (xMatix to external) or Bidirectional.Default Bidirectional.
External-id field (keyed upsert)The external field holding the xMatix id, marked External Id and Unique there.Without it, outbound writes cannot match existing records. Compile refuses an outbound entity without it when the provider supports keyed upsert.
Composite external key (inbound)A {field} template when the external id is not unique on its own.Inbound record entities only; cannot be changed here once records have synced.
Conflict policyOverrides the profile default.Blank inherits the default.
Store last-synced snapshotKeeps the last synced values as the base for a 3-way merge.Needed by Field-level merge and Manual; without it they behave as Last writer wins. Follows the policy until you change it yourself.
Delete propagationNone, Soft delete or Hard delete.Default None. Hard delete is physical and is refused for entities whose required child records sit outside the profile.
Child-record generationWhich side generates child records when a handler would create them.xMatix or the external system; default xMatix.
Execution rankRun order; lower runs first.Leave at 0 and use Apply derived ranks.
xMatix filterA predicate limiting which xMatix records are in play.Blank syncs all records the identity can see.
External filterA predicate in the provider's own query language (for Salesforce, a SOQL WHERE fragment without the keyword).Optional.
Skip staged rows where (Bulk lane)A single T-SQL condition that drops matching staged rows before the merge.Salesforce bulk entities only; no semicolons, comments, subqueries or data changes.
Payload kindRecord, Lines (child rows nested in a parent) or Composite (a Tally voucher written with its lines).Default Record. Lines are inbound only; Composite is outbound and Tally only, and needs Composite shape (JSON).
Terminal-status guard (JSON)Statuses that must not move backwards.An inbound write that would regress one opens a conflict instead.

Add mapping dialog

FieldWhat it meansNotes
xMatix fieldThe field on the entity.Required. Read-only fields are marked; never-mapped fields cannot be picked.
Field on (external object)The external field's API name.Required.
DirectionBoth ways, To external only, or To xMatix only.Default Both ways. A read-only xMatix field mapped inward warns you: map it To external only.
Is a reference (lookup / FK)Translates the value through another entity's ledger instead of copying it.Set automatically when you pick a lookup field.
Resolve throughThe entity in this profile whose ledger translates the key.Must be in the same profile.
When the reference cannot be resolvedWait, Defer, Drop or Fail.Default Defer. A reference with no target must use Drop.
TransformNone, dateFormat, valueMap, percentToFraction, amountByDirection, sumOf, template, zohoInvoiceDiscountAmount, defaultValue or geoPoint.A closed list.
Transform config (JSON)Settings for the transform, such as a value map.Must be valid JSON to save.
Exclude from the conflict checkLeaves this field out of conflict detection.For external formula or roll-up fields and derived values; the field loses merge protection.

Business rules

  • A new profile is always created in Draft with the Active switch on, Field-level merge as its default policy and a 120-second overlap window.
  • Profile names are unique. The connection must belong to the chosen app. Schedules must parse as six-field cron, on create, on save and again at compile.
  • An entity can be declared only once per profile. A field can be mapped only once per direction on an entity.
  • Compile stops on any error and writes no flow versions. Common errors: a never-mapped field, a reference with a target missing and a policy other than Drop, an outbound entity with no keyed-upsert field on a provider that supports one, Hard delete on an entity with outside children, and a Lines or Composite declaration that does not fit its rules.
  • Compile warns, but still compiles, for: Field-level merge without a stored snapshot, a snapshot stored for a policy that never reads it, Last writer wins, a reference to an entity at the same or a later rank, and an outbound entity without a keyed-upsert field on a provider that lacks one.
  • Compile switches each schedule trigger on only when Status is Active and Active is on. An empty Schedule switches the triggers off. Flows for entities no longer declared have their schedules switched off; their versions and runs are kept.
  • Reseed (per entity) and Reseed all make the next pass re-compare every record in both directions. Nothing is deleted or re-created.
  • Resume on a record clears its Excluded or Error hold and failure count. The last synced hash is kept, so the record is not pushed back as a change.
  • Removing a mapping keeps the ledger; the next pass re-hashes the smaller field set.

Example

A wholesaler keeps its customer accounts in Salesforce and wants them in xMatix every 15 minutes, with xMatix edits flowing back. An administrator opens Setup → Platform → Sync profiles, selects Start from template, picks the Salesforce template and ticks Account and Contact. They choose the existing "Salesforce" integration app and connection, paste the user id of the dedicated user "Sync Service", and select Create profile.

On Entities they select Apply derived ranks: Account moves to rank 0, Contact to rank 1. On Mapping for Account they run Discover fields, accept the Exact and Likely matches, and see "Keyed upsert available on Record_Key__c", which is adopted. They compile and read the warnings, which name the fields they chose to keep out of the conflict check.

On Schedule they enter 0 */15 * * * *, set Status to Active, save and confirm Activate, then compile again. Twenty minutes later the cursor lag shows a few minutes per direction, and Records lists paired accounts with status In sync.

Training

Practice exercise

In a sandbox whose integration app allows sandbox execution, create a blank profile for a test connection with one inbound entity and three mapped fields. Compile it, give it the schedule 0 */30 * * * *, set Status to Active and save — but do not compile again. Check the integration app's triggers: the schedule is not running. Now compile.

Expected result: after the second compile the trigger is on, and within 30 minutes the entity's cursor lag shows a value and paired records appear on Records. Then set Status to Paused, save and compile, and confirm the trigger is off.

Quick reference

  • Setup → Platform → Sync profiles; start from a template when one exists.
  • Saving entities or mappings changes nothing until you Compile.
  • Status Active plus the Active switch, then Compile, is what turns the schedule on.
  • Schedules are six-field cron in UTC, seconds first.
  • Use Apply derived ranks instead of guessing ranks.
  • Outbound needs a keyed-upsert field, or re-runs create duplicates.
  • Leave Delete propagation at None unless deletes must travel.
  • To pause: Status Paused, save, compile. Clearing the schedule box does not stop it.
  • Watch cursor lag, Records and the app's run history; the Cycles tab is not recorded.

Permissions

ActionWhat you need
See Sync profiles, open a profile, read every tabThe Manage integrations setup capability.
Create, edit, compile, reseed, remove, resolve conflicts, resume recordsThe same capability. Sync-profile actions do not check your role on the integration app.
Be the sync identityAny active user; their record-level access sets what the sync can read and write.

Without Manage integrations, Sync profiles does not appear in Setup and the sync-profile service refuses every request.

Configuration

  • Sync profile — Setup → Platform → Sync profiles → (profile): Schedule, Overlap window, Status, Nightly reconciliation, Reconcile window, Auto-repair (Schedule tab); Name, Default conflict policy, Sync identity, Active (Settings tab).
  • Conflict policies — on Settings (default) and per entity: Field-level merge (recommended) compares each field with the last synced snapshot and opens a conflict only for genuinely contested fields; xMatix wins and External wins settle contested fields automatically while still applying the other side's unrelated edits; Last writer wins (lossy) takes the later change stamp, which can be wrong when clocks differ; Manual holds every change to the record until someone decides.
  • Starter templates — Start from template (list) and Apply template (Entities tab). Templates exist per provider; see the Salesforce, Zoho and Tally pages for what each brings.
  • Integration app — Setup → Platform → Integrations: the connection and secrets the profile uses, the app's Active switch (off stops every flow), and Allow sandbox execution in a sandbox.
  • Sync identity user — a user account whose security profiles and record security bound what the sync can read and write.
  • Monitoring — Setup → Platform → Monitoring → Sync Monitor, for health and conflicts across profiles.

Common problems

The profile is Active but nothing runs

Compile after activating. Compile decides whether the schedule triggers are on, and it reads the status at that moment. Also check that the schedule is six fields, that the Active switch is on, that the integration app is active and, in a sandbox, that the app allows sandbox execution.

I paused the profile and it still runs

Pausing takes effect at the next compile. Save Status Paused (or turn Active off), then select Compile.

I cleared the schedule but it still runs on the old one

Clearing the Schedule box does not currently save an empty schedule; the old one is kept. Pause the profile and compile instead.

Compile warns that triggers "kept their own schedule"

Someone changed a generated flow's schedule on the integration app. That trigger no longer follows the profile. Set it back to the profile's schedule there if you want it to follow again.

Compile says "The declaration is not valid, so nothing was compiled"

Read each error: it names the entity and field. Fix it on the Entities or Mapping tab and compile again.

It runs but syncs nothing

The sync identity cannot see the records, the entity is inactive, a filter excludes everything, or an entity's cursor has no completed baseline (the cursor tooltip says deltas cannot be trusted until it is reseeded). Widen the identity deliberately, check the filters, or Reseed the entity.

Outbound passes create duplicates

The entity has no keyed-upsert field. Mark the xMatix-id field as External Id and Unique in the external system, run Discover fields to adopt it, and compile.

A record synced once and then stopped

Find it on Records. A record shown as Parked (Excluded) or Error is held until you select Resume. A Conflict row waits for a decision on the Conflicts tab.

"is already declared in this profile"

The entity is already on the Entities tab. Edit that row instead.

Common questions

What stops an update loop between the two systems?

Content hashing. Each synced record's mapped fields are hashed at every successful sync. A record that comes back unchanged — including the engine's own write echoing back — matches the stored hash and is dropped before anything else is considered. Convergence therefore does not depend on timestamps or on the other system saying who wrote what. Fields that each system holds a different value for by design, such as platform stamps, cannot be mapped at all, because they would look changed on every cycle.

How fresh is the data?

As fresh as the schedule: a 15-minute schedule means changes land within roughly 15 minutes plus the time a cycle takes. The engine is schedule-driven and does not subscribe to instant change feeds from the external system. To push xMatix changes outward the moment they happen, use an entity-event flow.

Can I sync only some records?

Yes, per entity and on either side. The xMatix filter limits which xMatix records are in play, and the external filter is passed to the external system in its own query language. The sync identity's access is a further limit. Compile after changing a filter.

What happens when both sides change the same record?

Fields changed on only one side move normally under every policy except Manual. Genuinely contested fields follow the policy: Field-level merge opens a conflict listing only those fields; the one-side-wins policies decide automatically. See sync health and conflicts.

Is it safe to compile often?

Yes. An unchanged declaration writes no new versions, and compile never moves watermarks or run history. It does re-apply the profile's status and schedule to the triggers, which is usually what you want.