Choose Contact types deliberately
ThecontactType field — Household, Organization, or Foundation — determines how Virtuous treats the record throughout the platform. Get this right at creation time; changing it later is operationally awkward.
The wrong choice causes downstream pain:
- Creating an Organization as a Household means the organization shows up alongside individuals in donor reports, distorting per-household metrics.
- Creating a Household as an Organization means the individual lacks ContactIndividuals to capture their name, birth date, or personal preferences.
- Creating a Foundation as a generic Organization misses the foundation-specific reporting Virtuous provides.
How to detect Contact type from your source data
Your source platform usually has enough signal to distinguish:
For ambiguous cases (a sole proprietor giving from a business name with their personal email), default to Household and tag the record
"Business-Donor" for the customer’s team to review and reclassify if needed.
Use a stable, predictable external reference
ThereferenceSource + referenceId pair is the single most important data-modeling decision for a partner integration. Every other matching, deduplication, and reconciliation pattern depends on it.
Three rules for the reference:
What “stable” means in practice
A reference is stable if it doesn’t change when the entity’s other attributes change. Specifically:- Email is not stable — donors change their email.
- Phone is not stable — donors change their phone.
- Name is not stable — donors change their name (marriage, transition).
- Address is not stable — donors move.
- Stripe Customer ID is stable — once issued, it identifies the same customer for their lifetime on Stripe.
- Your platform’s user ID is stable — assuming you use a real primary key, not a hash of mutable data.
When the source doesn’t have a stable ID
Some source platforms (older systems, CSV imports, manual data entry) don’t expose a stable identifier. Two patterns:- Generate one once and persist it. On first encounter, generate a UUID and store it alongside the source record. Use the UUID as
referenceIdon every subsequent submission. This works for any source with a writable database on your side. - Use a deterministic hash. Hash the most stable subset of fields (e.g.,
lowercase(email) + lowercase(lastname)) to produce a reproducible ID. Less robust because the inputs can still change, but workable for read-only sources where you have no writable storage.
Project codes are the API’s primary key for designations
Projects are the destination for Gift designations. TheirprojectCode field is the partner-friendly API identifier — short, human-readable, stable.
Three best practices:
Splitting designations: when to use multiple
A single Gift can be split across multiple Projects via thegiftDesignations[] array. Use a split when:
- The donor explicitly specifies multiple destinations.
- The source platform records a multi-Project intent (e.g., “10% to admin, 90% to programs”).
- The customer’s policy automatically allocates portions to specific funds (e.g., “5% of every gift to an endowment”).
Custom fields vs. tags: a decision tree
The two main ways to add structure beyond Virtuous’s built-in fields. They serve different purposes.Examples
Tag naming conventions
When your integration writes tags, use a consistent prefix that identifies the source:
The prefix lets the customer’s team visually distinguish “tags my staff applied” from “tags some integration applied” — and lets your integration code filter for “my tags” when synchronizing back to the source.
Capture, don’t infer, source-of-record data
A frequent partner integration mistake: re-deriving source-of-record fields from data the integration doesn’t authoritatively own. For example, computing a donor’s giving total in your integration’s database when Virtuous already calculateslifeToDateGiving.
The rule: store what your platform owns; query what Virtuous owns.
When the customer wants a report that mixes both — “donors on the Mailchimp Gold list who gave more than $1,000 last year” — pull the giving totals from Virtuous on demand rather than syncing them into your platform and risking staleness.
Designate ownership of each field per integration
In a multi-integration customer environment, multiple systems may write to the same Contact. Without explicit field ownership, two integrations will overwrite each other’s data. The pattern: document which fields each integration owns, both within your integration’s documentation and (ideally) in the customer’s runbook for managing their Virtuous setup. A typical breakdown for a fundraising-platform integration:
Your integration’s code enforces this — outbound writes only modify fields you own. Inbound reads (webhook handlers) apply changes only to fields the source platform owns.
See Build a Two-Way Sync — Pattern 2: per-field ownership for the implementation.
Capture audit metadata at creation, not in narration
Several pieces of metadata are useful for diagnostics later: when did the integration first sync this record, which version of the integration code wrote it, what was the source event. The natural impulse is to put these in ContactNotes — but notes are designed for human-readable observations, not machine-readable diagnostics. Better practice: capture diagnostic metadata as custom fields, not notes.JavaScript
Use Relationships sparingly and only when configured
Virtuous Relationships connect two Contacts (donor and spouse, parent and child, donor and recruiting fundraiser). They’re powerful but easy to misuse. Two rules:
Relationships are a “two-way edge in the social graph” — a wrong relationship is more confusing than no relationship. When in doubt, capture the linkage in a custom field instead and let the customer’s team formalize it as a Relationship if they want.
Plan for the customer’s reporting needs
The customer’s team will eventually want to build reports against the data your integration writes. Three things make their work easier:- Consistent tags and custom field values. “Major Donor” and “Major-donor” and “major_donor” are three different segments to Virtuous Query, even though they’re the same intent to a human.
- Predictable Project codes. The customer should be able to write
parameter: "Project", operator: "Is", value: "CLEAN-WATER"and know it returns the right gifts. Cryptic codes (P-2024-0317) frustrate this. - Useful
originSegmentCodevalues. This field captures “how did this Contact first enter Virtuous?” — set it to a stable, descriptive value ("FUNDRAISING-PLATFORM","STRIPE-DONATION","MAILCHIMP-SIGNUP") so reports can split donors by acquisition channel.
Where to go next
API Performance Tips
How to keep your integration fast and within rate limits at scale.
Error Recovery Patterns
The resilience patterns that complement good data modeling.
Custom Fields
The reference page for custom field reads and writes.
Funds, Campaigns, and Designations
The deeper reference for the Project hierarchy and designation structure.