Most small fundraising teams don't have an engagement problem. They have a definition problem. Every system your organization touches — email platform, event tool, CRM, donation page, texting app — records "engagement" its own way, and none of them agree on what counts. So when someone asks "which of our lapsed donors are actually warming up?" the honest answer is usually "let me pull four exports and guess."
A donor engagement taxonomy is the fix, but not in the way most people think. It isn't a scoring formula you copy off a blog. It's the boring, upfront agreement on what signals exist, what they're allowed to contain, and how they collapse into something a human can act on. Get that layer right and scoring becomes almost trivial. Skip it, and you end up with an "engagement score" that nobody trusts because no one can explain how it moved.
This post covers the signal layer specifically — allowed values, merge rules, how the messy reality of common CRMs maps into it, and the decision rules that turn a pile of touchpoints into one number.
Why engagement definitions drift across every organization
The drift is structural, not sloppiness. Here's a pattern that shows up almost everywhere:
Your email tool logs opens and clicks. Your event platform logs registrations and check-ins. Your CRM logs "activities" that a staff member typed in free text at 4:55pm on a Friday. Your donation processor logs transactions. Each of these was built by a different vendor solving a different problem, so each has a different idea of what a "signal" is and how granular it should be.
Nobody sits down and reconciles them. Instead, whoever builds the first dashboard makes silent decisions — "I'll count an email open as engagement" — and those decisions get baked in without documentation. Six months later a new hire counts opens differently, and now your quarterly board slide and your daily worklist disagree.
The deeper issue is that engagement signals mix two things that should stay separate: the raw event (a person did X) and the interpretation (X means they're interested). When those get fused early — when your CRM stores "Warm Lead" instead of "attended webinar on 3/12" — you lose the ability to re-score later. You've thrown away the evidence and kept only the verdict.
A good taxonomy keeps evidence and verdict on separate shelves. Signals are facts. Scores are opinions built from facts. You want to be able to change your opinion without rewriting history.
The signal layer: allowed values and why they matter
Start by deciding what a signal is in your world. For most small teams, an engagement signal has four required parts and nothing more:
Simplify donor management and fundraising workflows.
Givioly helps you organize campaigns, engage donors, and maximize fundraising impact seamlessly.
- Unified donor profiles
- Real-time donation tracking
- Automated impact reporting
No credit card required
-
Signal type — a controlled value from a fixed list (not free text)
-
Direction — did the donor initiate, or did we? (inbound vs. outbound)
-
Timestamp — when it happened
-
Source system — where it came from
The controlled list is the part people skip, and it's the part that matters most. If "signal type" can be anything a staffer types, you don't have a taxonomy, you have a comment field. Here's a workable starter list for a small nonprofit. Keep it short — 12 to 18 values is plenty. Bigger lists rot because nobody remembers them.
| Signal type | Direction | Typical source |
|---|---|---|
| gift_made | inbound | Payment processor / CRM |
| recurring_started | inbound | Processor |
| recurring_lapsed | inbound (implied) | Processor |
| email_click | inbound | Email platform |
| email_open | inbound | Email platform |
| event_registered | inbound | Event tool |
| event_attended | inbound | Event tool / check-in |
| form_submitted | inbound | Web / CRM |
| reply_received | inbound | Email / SMS |
| meeting_held | inbound | CRM activity |
| call_connected | inbound | CRM / phone |
| volunteer_shift | inbound | Volunteer tool |
| outboundemailsent | outbound | Email platform |
| outboundcallattempt | outbound | CRM |
| survey_completed | inbound | Survey tool |
Two things worth noticing. First, emailopen and emailclick are separate signals, not one. Opens are near-worthless now that Apple Mail Privacy Protection auto-fetches images and inflates open rates — treating them the same as a click will quietly poison your scoring. Keep them distinct so you can weight opens near zero without deleting the data.
Second, outbound signals exist in the taxonomy but they aren't engagement. A donor didn't engage because you emailed them. Outbound belongs in the list because you need it for context and cadence rules, but it should never lift an engagement score. Teams that forget this end up with "highly engaged" donors who are really just people the team emails a lot.
Merge rules: collapsing duplicate and near-duplicate signals
This is where scores go sideways. The same real-world action often generates multiple raw records. A donor clicks an email link, lands on your donation page, and gives — depending on your tools that might fire an emailclick, a formsubmitted, and a gift_made within ninety seconds. Count all three at full weight and one action inflates into three, making your busiest donors look artificially hot.
You need explicit merge rules. A few that hold up in practice:
-
Same signal type, same donor, within a window → collapse to one. Three
email_openevents on the same send within 24 hours is one signal, not three. Window length depends on the signal; opens and clicks want a short window, gifts want none (every gift is real). -
Chained signals from one session → keep the strongest. If
emailclick→formsubmitted→gift_madehappen inside a 10-minute window, the gift dominates. The click and form can stay as evidence but shouldn't independently add score. -
Never merge across direction. An outbound call attempt and an inbound reply are two different facts. Collapsing them hides whether the donor actually responded.
-
Never dedupe gifts. Two gifts an hour apart are two gifts, even if that's unusual. Suppress them at the score layer if you want, but keep both records — you'll need them for reconciliation.
The pattern underneath all of this: merge at the evidence layer using time and identity, but resolve conflicts by strength, not recency. A gift beats a click even if the click came later in the session.
Getting these rules written down matters more than getting them perfect. A documented, slightly-wrong merge rule is fixable. An undocumented one that lives only in someone's dashboard formula is a landmine. This is exactly the kind of decision that belongs in your written data rules — the same discipline covered in a practical fundraising data governance policy, where who's allowed to change definitions matters as much as the definitions themselves.
Mapping the taxonomy onto common CRMs
This is where the abstract taxonomy meets the annoying reality of whatever platform you actually run. The goal isn't to change your CRM — it's to define a translation layer, a mapping from what each system records into your controlled signal list.
Salesforce (NPSP). Engagement usually lives in Activities (Tasks and Events) plus Campaign Member statuses. The trap is that Task "Type" and "Subject" are wide open, so callconnected might be recorded as "Call," "Phone," "Left VM," "Spoke w/ donor," and a dozen other variations depending on who logged it. Your mapping needs a lookup table that translates those free-text variants into one clean signal. Campaign Member "Responded = true" is a decent proxy for eventregistered or event_attended depending on how you configure statuses — but only if your team is disciplined about which campaign statuses mean what.
Bloomerang. Interactions are your friend here; they're reasonably structured and have a Type and Subtype. Map Interaction Types to your signal list directly. The gotcha is that email opens/clicks from the built-in email tool land in a different area than logged Interactions, so your mapping has to reach across two data sources to build a full picture.
DonorPerfect. Contacts (activity records) carry a lot of engagement, but a huge amount ends up in general notes fields that never make it into structured reporting. If half your meeting_held signals live in a notes blob, no taxonomy will save you — you have to move that capture into structured fields first.
HubSpot (used by some nonprofits). Rich native engagement tracking, which is a blessing and a curse. It'll happily log dozens of low-value signals, so your mapping should be subtractive — decide what to ignore, not just what to keep.
The universal mapping mistake is trying to reconcile these systems at the report level instead of at the record level. If you only translate them inside a dashboard, every new report re-invents the logic. Define the mapping once, apply it as records land, and every downstream view inherits the same rules. This is the same integration discipline covered in a pragmatic framework for fundraising metrics and attribution — consistent definitions upstream so the numbers agree downstream.
A simple mapping worksheet
-
Source field/value — the raw thing your system stores ("Call," "Left VM," "Responded=true")
-
Signal type — the controlled value it maps to
-
Notes / conditions — any rule ("only if outcome = connected")
Start mapping the highest-volume or highest-value raw values first so the worksheet gives immediate improvements to reports and outreach.
Fill one row per raw value. It's tedious. It's also the single highest-leverage hour of work in this whole exercise, because it's the artifact a new hire reads to understand your data.
Decision rules: turning touchpoints into one engagement score
Once signals are clean, merged, and mapped, scoring is mostly bookkeeping. The job is to convert a stack of dated signals into one number a gift officer can sort by. A few decision rules keep it sane:
-
1. Weight by signal, decay by time. Not all signals are equal, and none stay fresh forever. Assign a base weight per signal type, then apply time decay so a gift from last month counts more than one from two years ago. A rough starting scheme: -
giftmade: high base weight, slow decay -eventattended,meetingheld,replyreceived: medium weight, medium decay -emailclick,formsubmitted: low weight, fast decay -email_open: near-zero - outbound signals: zero contribution to score -
2. Cap contribution per signal type per window. Otherwise the donor who clicks every email looks more engaged than the donor who just gave $500. Cap
email_clickat, say, its weight times three per quarter regardless of how many clicks actually happened. -
3. Score on a rolling window, not lifetime. Engagement is a "lately" question. A 12- or 18-month rolling window keeps the score answering "is this person warm now" instead of "were they ever active."
-
4. Keep the score explainable. If a gift officer can't look at the top three contributing signals and understand why someone scored a 74, the score is dead on arrival. Store the contributing signals alongside the number. A score you can't explain gets ignored the first time it disagrees with someone's gut.
Here's a compact worked example. Take a mid-level donor over an 18-month window:
-
One
gift_madeseven months ago → base 40, decayed to ~30 -
One
event_attendedthree months ago → base 15, decayed to ~12 -
Four
email_clicksignals across the window → base 3 each, capped and decayed to ~7 total -
Eleven
email_opensignals → weighted near zero, contributes ~1 -
Six
outboundemailsent→ contributes 0
Total: roughly 50 on a 0–100 scale. The number isn't the point — the point is you can read exactly why it's 50, and if it climbs to 65 next month, you'll know which signal moved it.
When a formal taxonomy is worth it — and when it isn't
When it makes sense: you're running more than one channel, you've got a CRM plus at least an email tool and a donation page, and you've started asking "which donors should we reach out to" without a clean answer. That's the point where undefined signals actively cost you — either in missed upgrade opportunities or in staff time spent reconciling exports.
When it's overkill: if you're a one-person shop with a single spreadsheet and 150 donors you know by name, a scoring taxonomy is theater. Your engagement model is your memory, and it's fine. Build the taxonomy when your donor count outgrows what one person can hold in their head — usually somewhere past a few hundred active relationships.
Who should not do this: teams that haven't yet cleaned up identity resolution. If the same donor exists as three records across your systems, no taxonomy will help — you'll be scoring fragments of people. Fix duplicate and matching problems first, then layer signals on top. Scoring garbage identities just produces confident garbage.
What breaks as you grow
The taxonomy that works at 400 donors strains at 4,000, and it's worth knowing where the seams are before you hit them.
Signal volume outpaces manual capture. At small scale, staff log meetings and calls by hand and it mostly works. As volume grows, the human-entered signals — often your highest-value ones — get logged inconsistently or not at all, while the auto-captured low-value signals (opens, clicks) keep flowing. Your score quietly tilts toward noise. The fix is structural: make the important signals as easy to capture as the trivial ones, ideally through required fields and quick-log actions rather than free-text notes.
Merge windows that worked stop working. A 24-hour dedup window is fine until you're sending enough email that a donor legitimately engages with two different campaigns in a day. Merge rules need occasional revisiting as send volume climbs.
Definitions fork across teams. Once you have more than a couple of people building views, someone will invent a private definition of "engaged." The only defense is a single documented source of truth for signal types and weights, owned by one person, changed on purpose. This is governance, not tooling — the platform matters less than the discipline of deciding once and writing it down.
A real scenario
A small arts nonprofit — two-person development team, roughly 2,600 active donors — ran on a CRM plus a separate email platform and an event tool. Their "engagement report" was a manual monthly export that took most of a day and that nobody fully trusted, because event attendance and email activity lived in different files that were joined by hand.
The core issue wasn't the score, it was upstream. Email opens were being counted the same as clicks, so their "engaged" list was full of Apple Mail auto-opens. Call outcomes were free text, so connected calls and voicemails were blended together. And one email-click-to-donation flow was triple-counting a single gift.
They didn't buy anything new. They wrote a 14-value signal list, built the three-column mapping worksheet for each system, set merge rules (collapse same-day opens, let gifts dominate their session, drop outbound from scoring), and defined a simple weight-and-decay score on an 18-month window.
The report went from a full day to something they could refresh in well under an hour, because the definitions were fixed instead of re-argued every month. More usefully, their outreach list stopped surfacing dead accounts. Over the following two quarters they found somewhere around 40–50 genuinely-warming lapsed mid-level donors the old export had been burying under email noise — people worth a real phone call. A few of those reactivated. Not a dramatic revenue story, but a real one, and it came entirely from cleaning up definitions rather than adding anything new.
The takeaway
Engagement scoring fails far more often at the signal layer than at the math layer. If your signals are a controlled list, your merge rules are written down, your CRM values map cleanly into that list, and your score keeps its evidence attached — the actual scoring formula almost doesn't matter. You can tune weights forever; you can't tune your way out of ambiguous inputs.
Build from the bottom. Define the signals, agree on the merges, map each system once, and only then argue about weights. It's less exciting than a scoring model, but it's the part that decides whether anyone believes the number you hand them.
Ready to elevate your fundraising efforts?
Join 2,000+ nonprofits using Givioly to save time, increase donations, and build lasting donor relationships.