Skip to main content

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

Virtuous’s “Giving Overview” computed/reporting fields — Rolling Year Giving, Life To Date (+Passthrough) Gift Count, Segment Code, Contact Type, Gift Type, Largest/Last Gift Amount Overall, First/Last Gift Date Overall, Life To Date Gift Count — are not supported. These are fields Virtuous computes on top of its own Gift/Contact records; WeGive’s integration only ever pulls the underlying real Gift/Contact/Project/Segment/RecurringGift records (see the mapping tables below), never Virtuous’s own derived reporting fields. WeGive computes its own, narrower set of giving aggregates directly on the donor record instead — a lifetime total and a fixed calendar-year total. There is no equivalent for an arbitrary rolling 12-month window, a passthrough-adjusted lifetime total, or Virtuous’s Segment Code/Contact Type/Gift Type fields — if you need one of these for an audience rule, you’ll need to approximate it using WeGive’s standard date-range and transaction-amount filters instead.
Detailed field-level mappings live on the per-object pages:

Correlation Fields

WeGive tracks the corresponding Virtuous record using these columns: 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

There’s no dashboard setting that turns push or pull on/off per object type — every object type listed above pushes and pulls unconditionally once the integration is enabled. See Configuration Options for the full picture.
  • 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.