Virtuous Data Mapping Overview
Data Mapping Overview
This document describes how the WeGive donor platform maps to Virtuous CRM objects and how each object is synchronized in both directions. The mappings here reflect the actual behavior of the integration, including the specific Virtuous API endpoints, fields, and transformations used.
Object Mapping Summary
| WeGive Object | Virtuous Object | Push (WeGive → Virtuous) | Pull (Virtuous → WeGive) |
|---|---|---|---|
| Donor (individual) | ContactIndividual (within a Contact) | Create/update | Create/update |
| Donor (company) / Household | Contact (Organization / Household) | Create/update | Create/update |
| Transaction | Gift | Create/update (batch or real-time) | Create/update |
| Fund | Project | Create only | Create/update |
| Campaign | Segment | Create/update | Create/update |
| Scheduled Donation | RecurringGift | Create/update | Create/update |
Detailed field-level mappings live on the per-object pages:
Correlation Fields
WeGive tracks the corresponding Virtuous record using these columns:
| WeGive Record | Column(s) | References |
|---|---|---|
| Donor (individual) | virtuous_contact_id | The parent Virtuous Contact |
| Donor (individual) | virtuous_contact_individual_id | The Virtuous ContactIndividual |
| Donor (individual) | virtuous_is_primary_contact_individual | Whether this donor is the Contact’s primary individual |
| Donor (company) | virtuous_contact_id | The Virtuous Contact (no individual) |
| Household | virtuous_id | The Virtuous Contact |
| Transaction | virtuous_id | The Virtuous Gift ID, or a synthetic batch ID prefixed btch_ |
| Fund | virtuous_id | The Virtuous Project |
| Campaign | virtuous_id | The Virtuous Segment |
| Scheduled Donation | virtuous_id | The Virtuous RecurringGift |
Transactions sent through the batch importer are marked with a synthetic ID like btch_WeGive_Import rather than a real Gift ID. The integration treats btch_* values as “synced but not individually addressable” and will not attempt to update those gifts.
Sync Directions
Push and pull are configured per object. In practice:
- Push is the primary direction. Donors, transactions, funds, campaigns, and scheduled donations are pushed to Virtuous by default.
- Pull is opt-in and typically used for organizations that treat Virtuous as a system of record.
- Funds are create-only on push — once a Fund has a
virtuous_id, the integration does not update the VirtuousProject.
Push triggers
- Real-time: When
real_timeis enabled, individual transactions are pushed as they occur, and a Virtuous webhook (contactUpdate) notifies WeGive of contact changes. Real-time transaction push is skipped entirely whenreal_timeis disabled. - Batch: Transactions are sent in batches (default 100 per request) to
v2/Gift/Transactions. This is the default path for bulk processing.
Related-entity push
Pushing a transaction or scheduled donation will first push any related records that don’t yet have a virtuous_id — the owner/donor, the campaign, and the fund(s) — so the gift can reference real Virtuous IDs.
Matching Logic
When importing from Virtuous, records are matched in this order:
Contacts / Donors
virtuous_contact_individual_idon the donorvirtuous_contact_id+ primary-individual flag (or the company donor forOrganization-type contacts)- Create new
Transactions
virtuous_id(the Gift ID)- The
wg_idcustom field that WeGive wrote on the gift (links back to the original WeGive transaction) - Create new
Funds / Campaigns / Scheduled Donations
- Matched on
virtuous_id.
Virtuous API Endpoints Used
All requests use base URL https://api.virtuoussoftware.com/api/ with a Bearer API key. Write requests append ?disableWebhookUpdates=true so WeGive’s own writes don’t trigger echo webhooks.
Pull (query) endpoints
Pulls page through Virtuous’s query endpoints (1000 records per page), filtered by the configured pull_by date field using OnOrAfter / OnOrBefore:
POST Contact/Query/FullContactPOST ContactIndividual/QueryPOST Gift/Query/FullGiftPOST Project/QueryPOST Segment/QueryPOST RecurringGift/Query
Push endpoints
POST Contact,PUT ContactIndividual/{id},POST/PUT ContactMethod,POST/PUT ContactAddressPOST Gift,PUT Gift/{id}(real-time, single gift)POST v2/Gift/Transactions(batch gift import)POST ProjectPOST Segment,PUT Segment/{id}POST RecurringGift,PUT RecurringGift/{id}POST Webhook(registers thecontactUpdatewebhook when the integration is enabled)
Reliability
- Rate limiting: On HTTP 429, requests retry up to 3 times, sleeping until the
X-RateLimit-Resettime (capped at 240 seconds). - Timeouts: Requests use a 300-second timeout.
Amount Handling
WeGive stores monetary amounts in cents; Virtuous uses dollars. All amounts are divided by 100 on push and multiplied by 100 on pull.
Notes
- Donors with no first or last name are pushed with the sentinel values
FNU(First Name Unknown) /LNU(Last Name Unknown), which Virtuous requires. These sentinels are stripped back tonullwhen WeGive creates user logins on pull. - The integration never deletes Virtuous contact methods that exist in Virtuous but not in WeGive, to preserve data entered directly in Virtuous.
This overview reflects the integration as implemented. See the per-object pages for exact field mappings.