How Sync Works

How Sync Works

Every native integration follows the same pattern: fetch data from the source system, decide what to do with each record, and apply the result to your event in ExpoPlatform. This page walks through that pattern so the rest of the section makes sense.


The basic flow

When a sync starts — either on schedule or triggered manually — the integration contacts the source system, retrieves the current list of records (visitors, exhibitors, or both, depending on the integration), and works through each record one by one.

For every incoming record, the sync:

  1. Looks it up in your event. Does a matching record already exist in ExpoPlatform?

  2. Compares the data. If it exists, has anything changed since the last sync?

  3. Applies the configured rules. Category mapping, filters, field mapping — see Shared Settings.

  4. Writes the result. Creates a new record, updates an existing one, or skips it with a documented reason.

Once every record has been processed, the sync is marked complete and the outcome is recorded in the sync history.


How records arrive

Different source systems expose their data differently, so native integrations use one of two trigger styles:

  • Webhook-driven. The source system notifies ExpoPlatform the moment a record changes. The integration then fetches that record and processes it. Visit is the main example.

  • Scheduled polling (Auto-Update). ExpoPlatform checks the source system on a schedule — typically every five minutes — and fetches whatever has changed since the last successful sync. Most integrations work this way.

Either way, the record goes through the same processing pipeline. The trigger style only changes when the sync runs, not what happens inside it.


Full syncs vs incremental syncs

The very first sync for a new subscription is a full sync — every record in scope is fetched from the source, because there's no previous sync state to build from.

Every scheduled sync after that is incremental — it fetches only the records that have changed since the last successful run. Incremental syncs are much faster because the source system does the filtering.

Not every integration fetches updates the same way, though. Some (like Visit, Aventri, CDS, Genesis, MapYourShow) pull both new registrations and edits to existing records on each incremental run. Others (like Aditus Visitors) can only pull new registrations — the source system doesn't offer a way to detect updates. Each integration's page documents its specific behaviour.

You can also trigger a manual full resync at any time. This ignores the incremental sync cursor and fetches every record in scope again — useful after initial setup, after a period of downtime, or when you want to force a fresh look at everything.


What happens when a record is re-imported

When a record already exists in ExpoPlatform and the sync fetches it again, the update field mapping decides which fields get overwritten and which are preserved.

  • Field included in update mapping — the source system is authoritative for that field. Its value in ExpoPlatform is replaced on every re-import.

  • Field excluded from update mapping — ExpoPlatform is authoritative. Any edits made in ExpoPlatform (by managers or by the visitor themselves) survive future syncs.

Most events configure the update mapping minimally, including only the handful of fields that genuinely change in the source (often registration status or category), and leaving everything else ExpoPlatform-managed after first import.

The create field mapping is a separate set of rules, applied once when a record is first imported. It's not affected by the update mapping.


Subscriptions: active and paused

Each integration is configured as a subscription to a specific entity type (visitors or exhibitors) for a specific event. Subscriptions can be in one of two states:

  • Active — the scheduler will run syncs for this subscription on the configured cadence.

  • Paused — the scheduler skips this subscription entirely. No syncs are triggered until you resume it.

Pausing takes effect from the next scheduled cycle. Any sync already in progress when you pause will complete normally. Extended pausing means data drift — the event in ExpoPlatform will fall out of step with the source system until the subscription is resumed.


Sync results: created, updated, skipped, failed

Every sync run produces four counters:

Result

Meaning

Created

A new record was created in ExpoPlatform.

Updated

An existing record was updated.

Skipped

The record was intentionally not written. This is normal — most skips are records that haven't changed, or records excluded by a configured rule (filter, unmapped category, etc.). Each skip is recorded with a reason.

Failed

The record couldn't be processed. Rare. Failed usually means a system-level error (a database write that didn't complete, or repeated delivery failures from the source system).

Skipped is not a failure. It's the normal outcome for filtered records, unchanged records, and records deleted in the source. A healthy sync often has a large skipped count — sometimes 100% during quiet periods when nothing has changed.

Failed should be close to zero in a healthy system. A sustained non-zero failure count means something is wrong and warrants investigation. See Troubleshooting.


What a "sync job" is

Every time a sync is triggered — scheduled or manual — the system creates a Sync Job. The Sync Job owns the whole sync from start to finish and shows up in the sync history for that subscription. For most integrations, a Sync Job runs a single sync operation. A few multi-step integrations run several operations under one job (for example, fetching a list first and then fetching detailed records for each item on the list).

The sync history in the admin UI shows one row per Sync Job with its status, duration, and result counts. Expand a row to see the full breakdown.


Scheduled syncs and full resyncs

For a deeper look at how scheduled polling works — the five-minute cadence, how the incremental sync cursor advances between runs, and how to configure the optional daily full resync — see Scheduled Syncs and Full Resyncs.