Skip to content

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 ObjectVirtuous ObjectPush (WeGive → Virtuous)Pull (Virtuous → WeGive)
Donor (individual)ContactIndividual (within a Contact)Create/updateCreate/update
Donor (company) / HouseholdContact (Organization / Household)Create/updateCreate/update
TransactionGiftCreate/update (batch or real-time)Create/update
FundProjectCreate onlyCreate/update
CampaignSegmentCreate/updateCreate/update
Scheduled DonationRecurringGiftCreate/updateCreate/update

Detailed field-level mappings live on the per-object pages:

Correlation Fields

WeGive tracks the corresponding Virtuous record using these columns:

WeGive RecordColumn(s)References
Donor (individual)virtuous_contact_idThe parent Virtuous Contact
Donor (individual)virtuous_contact_individual_idThe Virtuous ContactIndividual
Donor (individual)virtuous_is_primary_contact_individualWhether this donor is the Contact’s primary individual
Donor (company)virtuous_contact_idThe Virtuous Contact (no individual)
Householdvirtuous_idThe Virtuous Contact
Transactionvirtuous_idThe Virtuous Gift ID, or a synthetic batch ID prefixed btch_
Fundvirtuous_idThe Virtuous Project
Campaignvirtuous_idThe Virtuous Segment
Scheduled Donationvirtuous_idThe 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 Virtuous Project.

Push triggers

  • Real-time: When real_time is 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 when real_time is disabled.
  • Batch: Transactions are sent in batches (default 100 per request) to v2/Gift/Transactions. This is the default path for bulk processing.

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

  1. virtuous_contact_individual_id on the donor
  2. virtuous_contact_id + primary-individual flag (or the company donor for Organization-type contacts)
  3. Create new

Transactions

  1. virtuous_id (the Gift ID)
  2. The wg_id custom field that WeGive wrote on the gift (links back to the original WeGive transaction)
  3. 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/FullContact
  • POST ContactIndividual/Query
  • POST Gift/Query/FullGift
  • POST Project/Query
  • POST Segment/Query
  • POST RecurringGift/Query

Push endpoints

  • POST Contact, PUT ContactIndividual/{id}, POST/PUT ContactMethod, POST/PUT ContactAddress
  • POST Gift, PUT Gift/{id} (real-time, single gift)
  • POST v2/Gift/Transactions (batch gift import)
  • POST Project
  • POST Segment, PUT Segment/{id}
  • POST RecurringGift, PUT RecurringGift/{id}
  • POST Webhook (registers the contactUpdate webhook when the integration is enabled)

Reliability

  • Rate limiting: On HTTP 429, requests retry up to 3 times, sleeping until the X-RateLimit-Reset time (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 to null when 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.