Event data silos are the separate record sets one event leaves behind in systems that were
never built to read each other.

Registrations sit in the registration platform, presence in the
event app or webinar tool, contacts and opportunities in the CRM, spend in the ad accounts,
invoices with finance, membership in the AMS. Each of those sets is internally correct. They
disagree with one another because each system identifies a person by a different key, counts a
different population as an attendee, decides at a different moment that a record exists, and
stores it in its own currency and time zone.

This is written for associations, AMCs, and independent B2B organizers with paid registration
or ticket revenue, an annual event budget above $100K, and three or more systems that do not
talk to each other. The purpose is mechanical: find where your own records diverge, before
anyone argues about which number belongs in the board report.

## Why don't registration and CRM records add up?

Because they were never counting the same people, and never counting them with the same key.
Four mechanics produce almost every gap you will find, and they compound.

### The keys are different

Every system issues its own identifier, at its own moment, for its own purpose. The
registration platform stamps a registration ID on an order, and one order can cover several
people. The event app stamps a participant ID days later, when a profile or badge is generated.
Your CRM contact ID goes back to the first time anyone at the organization touched that person,
possibly years earlier. An AMS member ID belongs either to the individual or to their employer.
Ad platforms hold no person at all: the smallest unit is a campaign, an ad set, and a click.
Finance holds an invoice number and a cost center.

For one person to travel from an ad to a closed deal, this chain has to hold: campaign value,
registration ID, email address, CRM contact ID, account ID, opportunity ID, invoice number. Two
of those hops have no shared key at all. An ad platform never learned the person's name, so
spend reaches a registrant only through a campaign or UTM value carried onto the registration
record and typed the same way every time. Finance never learned the campaign, so an invoice
reaches an event through a project code, or through somebody's memory of what it was for.

Email is the one key that shows up in more than one system, and it is the weakest of them. A
person registers with a work address, sits in the CRM under an address they typed into a form
2 years ago, and appears in the AMS under a personal address attached to an individual
membership. Assistants register on behalf of executives, group inboxes register 3 people,
domains change after an acquisition. Plus-addressing, a trailing space, and a capitalized first
letter each produce a miss under exact matching. The count of unmatched rows therefore tells
you more than the match rate does: the rate is a summary, the unmatched pile is a list you can
read.

### "Attendee" means several different populations

Ask 5 systems how many people attended one conference and you can get five defensible
numbers.

| What the system counted | Where it comes from |
|---|---|
| Registered and paid | Registration platform, orders with a captured payment |
| Registered, including comped, staff, speakers, and waitlist | Registration platform, all rows |
| Scanned at the door at least once | Onsite check-in |
| Present in at least one session | Session scanning or the event app |
| Joined the stream for any length of time | Webinar or virtual platform |
| Watched the recording afterwards | Video platform, often reported as attendance |

Nothing above is a mistake. Each population answers a different question, and the word
"attendee" hides which question was asked. [Event attendance tracking](https://eventiq.io/md/blog/event-attendance-tracking)
keeps the collection method on every record for that reason. The virtual side adds arithmetic of its own: a
person who drops off and rejoins produces two participant rows, and a laptop plus a phone
produces two more. The platform counted connections, correctly, and the report reads them as
people.

### The moment of record is different

Systems also disagree about when a thing counted. One platform records a registration at form
submission, another at payment authorization, a third at payment capture, and finance at
invoice issue. Cancellations and transfers are handled 3 ways: some platforms delete the
row, some flag it, some keep the original beside its replacement. A total you pull today for a
March that closed months ago can differ from the total you pulled in April.

Ad platforms restate. Conversions are credited back to the date of the click and land in the
report days after it, so the cost per registration you quoted for last week keeps moving after
last week ended. In the CRM, the contact created date is not the registration date, and neither
is the campaign member date. Finance records revenue by accounting period, so a December
conference invoiced in January sits in two different years depending on which system you ask.

### The units are different

Currency lives on the row in most systems, so a total means something only once someone states
the rate and the date it was taken. An ad account converts at its own daily rate, finance at a
month-end rate, and a sponsorship contract may be written in a third currency.

Time zones do the same to dates. The registration platform stamps in UTC, the ad account in the
account's zone, the CRM displays in the viewing user's zone, and the event runs in venue local
time. "Registrations on the final day" then covers four different 24-hour windows, and a
daylight saving change moves them again.

## What breaks when you export to spreadsheets?

A spreadsheet is a snapshot with no memory: nothing in the file records which system produced
it, which filter was applied, or what day it was pulled. Five things go wrong on the way, and
the second export is where most of them surface.

1. Row counts change for periods that are already closed. Late records arrive, refunds post,
   the platform runs its own cleanup, or a default filter changed in a product release. The
   file you saved in April and the file you pull today describe the same March differently.
2. Columns move. A platform update adds a field, every column after it shifts one place, and
   the formula pointing at column H keeps returning a value. It is now the wrong field, and
   nothing announces that.
3. Values get retyped on open. Long member IDs turn into scientific notation and lose their
   leading zeros, so two distinct IDs collapse into one; 03/04/2026 reads as March in one
   locale and April in another. Every lookup keyed on those columns is wrong in a way that does
   not look wrong.
4. Lookups fail with no error. A lookup against last month's key list returns not-found for
   rows that are perfectly valid, someone filters those rows out to tidy the sheet, and the
   total drops with no line explaining the drop.
5. Corrections never travel back. The email typo you fixed in the file is still wrong in the
   registration platform, so the next export undoes your work, and the corrected version lives
   only in one person's copy.

There is a 10-minute test for this. Export the same closed period twice, a week apart, from
the same system with the same filters, then compare the row count and the sum of one money
column. Any difference is that system restating history behind you. Run it on the registration
platform, the CRM, and one ad account.

## What does it take to join these records?

The work takes a few days, and most of it is deciding things rather than building them. All of
it can be done on one past event before anything in your stack changes.

1. Pick one finished event that closed at least 90 days ago, so the pipeline behind it has had
   time to move.
2. Before pulling anything, ask each system owner for their number in writing, with the date
   they pulled it: registrations, attendees, contacts created, opportunities linked, spend,
   cost. Disagreement here is the finding, so record the numbers as they arrive instead of
   reconciling them in conversation.
3. Export one row per person from each system, keeping every identifier it holds and keeping
   the raw text. No sorting, no cleanup, no merged cells.
4. Normalize email for comparison only: trim whitespace, lowercase. Leave the original column
   beside it, because the original is what the source system matches on later.
5. Count the overlap in 3 buckets: in both registration and CRM, in registration only, in
   the CRM only. The three must sum to the total. If they do not, a row is counted twice.
6. Read the registration-only pile and classify it: no email at all, personal domain, obvious
   typo, group inbox, alias of an address you hold. The proportions tell you what a matching
   rule can and cannot fix. Then read the CRM-only pile and check whether a colleague registered
   those people under an order in someone else's name.
7. For each system, write one sentence naming which population its attendee number covers,
   using the table earlier on this page, and put the sentences side by side.
8. Pull registrations for the final day of the event in each system's own time zone, then again
   in venue local time, and see which totals move.
9. Write the outcome on one page: which numbers agree, which do not, by how much, and which of
   the four mechanics explains each gap.

Whatever you build after that, the joined record has to carry 4 things on every row, or it
will produce a cleaner number than your data supports: the original identifier from each
source, rather than a new internal one that replaces it; the match result, meaning matched,
unmatched, or no email to match on; the source system and the record's own timestamp; the
currency as the source stated it, beside any converted value.

Treat the unmatched pile as a finding. A join that drops what it could not match, without
saying so, hands finance a total that looks complete, and nobody in the room can say how
complete it is. Someone also has to own the written definitions, because a rule living inside a
query is a rule the reader of the chart cannot see. Naming those owners is the work of
[event data management](https://eventiq.io/md/event-data-management). Which layer is supposed to hold those
definitions is a question about [the event tech stack](https://eventiq.io/md/blog/event-tech-stack) rather than
about this page, which stays on the mechanics that make the numbers differ in the first place.

## What stays in each system?

Joining records leaves them where they are. Every system stays the record of the thing it was
bought to run, authoritative about a narrow slice and blind to the rest.

| System | What it holds as truth | What it has no way of knowing |
|---|---|---|
| Registration and ticketing | Who registered, ticket type, order value, check-in | Whether that person joined a session, became a deal, or cost anything to reach |
| Event app or virtual platform | Presence, time in session, questions, booth visits | Who paid, and whether the profile is the same human as a registration row with a different email |
| CRM | Contacts, accounts, opportunities, stages, close dates | Who actually showed up, and what the campaign cost |
| Ad platforms | Spend, impressions, clicks, and conversions per campaign | Who the person is |
| Finance | Invoices, purchase orders, accounting period, reporting currency | Which event or campaign a shared invoice belongs to |
| AMS, such as iMIS, Fonteva, or Nimble | Membership status, dues, chapter, member ID | Non-member attendees, pipeline, and marketing spend |

Three things live in none of them: the definition of an attendee your organization agreed on,
the rule that decides whether a deal counts toward an event, and the result of matching one
system's people against another's. Those belong wherever your report is assembled, which is why
they survive a change of any system underneath.

For the metrics you calculate once the records sit side by side, see
[event marketing analytics](https://eventiq.io/md/event-marketing-analytics). For the rule that credits a deal to an
event, see [event marketing attribution](https://eventiq.io/md/event-marketing-attribution). The arithmetic is in
the [event ROI guide](https://eventiq.io/md/event-roi), and the
[post-event report template](https://eventiq.io/md/blog/post-event-report-template) has a data coverage field, which
is where the unmatched pile gets written down instead of smoothed over.

## Where EventIQ fits

EventIQ replaces nothing. It connects on top of the platforms you already run:
registration and ticketing (Cvent, Zoom, Swapcard, StubHub), CRM (Salesforce,
HubSpot, GoHighLevel), and marketing (Google Ads, Meta Ads, LinkedIn Ads,
Mailchimp, Google Analytics). Platforms with an API outside that list are
connected on request.

Registrations and attendance stay separate records. Contacts are matched by exact
email, and every record keeps its result: matched, unmatched, or no email.
Salesforce deals, stages, and close dates link to an event through a campaign
relationship you confirm. Marketing spend sits by event and channel, with the
author of every change. Records sync on a schedule: Swapcard every 15 minutes,
Cvent every 30, Zoom every 2 hours, Salesforce every 4. The Event Dashboard and
the Portfolio Dashboard show them in one view, and a forecast is visible before
the event.

Association management systems with an API are connected on request during
onboarding. Ask any vendor, including us, which membership records reach the
report today and which still arrive by export.

## See the match result on every row

[Book a demo](https://eventiq.io/#early-access) to see registration and CRM records side by side on a sample
event, with the match result on every row: matched, unmatched, or no email to match on. The
demo takes 20 minutes.

---

HTML version: https://eventiq.io/blog/event-data-silos
