The core resources
The CRM+ API exposes a relatively small set of first-class resources. Almost every partner integration touches some subset of these:| Resource | What it represents | Typical partner use |
|---|---|---|
| Contact | A household, organization, or foundation — the unit a donor “belongs to.” | Synced from your platform when a donor or constituent is created or updated. |
| ContactIndividual | A person inside a Contact. Households have one or more ContactIndividuals. | Created alongside a Contact for individual-typed donors. |
| ContactAddress | A postal address belonging to a Contact. | Updated when a donor moves or corrects their address. |
| Gift | A single donation record. | Pushed from external giving platforms into Virtuous as the authoritative giving record. |
| GiftDesignation | An allocation of a Gift to a Project (a portion of the gift that funds a specific purpose). | Set when recording a gift to indicate what the donor is supporting. |
| Project | A fundable purpose or program (e.g., “Clean Water Initiative”). | Referenced when designating gifts; rarely created by partners. |
| Campaign | A time-bound fundraising effort grouping projects, segments, and goals. | Read-only from the CRM+ API — managed inside Virtuous. |
| Segment | A grouping of contacts for outreach, reporting, or campaign association. | Used to target communications or report on giving cohorts. |
| RecurringGift | An ongoing donation schedule. | Created when a donor starts a recurring giving plan in your system. |
| Pledge | A commitment to give a specific amount over time. | Used to track committed-but-not-yet-paid gifts. |
| Webhook | A subscription that delivers real-time events to your endpoint when records change. | Replaces polling for incremental sync. |
How the resources relate
The Contact, Gift, and Project resources form the spine of the model. Most partner integrations operate on this triangle: donors (Contacts), their giving (Gifts), and what those gifts fund (Projects, grouped under Campaigns). A few key relationships to internalize:- A Contact is not a person. A Contact is the household or organization record. The people inside a Contact are ContactIndividuals. A household Contact named “Wayne Family” might contain two ContactIndividuals (Bruce and Selina); an organization Contact named “Wayne Enterprises” might contain ContactIndividuals for the donor-facing employees. Sending personal name fields (
firstName,lastName) to the Contact resource is one of the most common partner-integration mistakes — they belong on ContactIndividual. - A Gift can fund multiple Projects. A donor giving 300 to “Clean Water” and $200 to “Education.” Each split is a separate GiftDesignation. A gift always has at least one designation.
- Campaigns are organizing context, not the funding destination. Money flows to Projects (via GiftDesignations), not directly to Campaigns. Campaigns are read-only from the API — they are managed inside the Virtuous UI.
- RecurringGifts and Pledges generate Gifts. A RecurringGift is the schedule; each successful payment on that schedule becomes a Gift. A Pledge is a future commitment; each payment toward the pledge is a Gift.
The two patterns for writing data into Virtuous
CRM+ exposes two architecturally different ways to create Contacts and Gifts from external systems. The choice of pattern matters more than any individual field decision — it determines whether your integration produces duplicates, whether it benefits from Virtuous’s matching logic, and how soon the records appear in the UI.Pattern 1: Transaction (recommended for partners)
The Transaction endpoints —POST /api/Contact/Transaction for contacts and POST /api/v2/Gift/Transaction for gifts — place incoming records into a holding state. A nightly batch processes them with Virtuous’s matching algorithms: contact deduplication by email, phone, address, and reference IDs; recurring-gift matching; designation resolution; and pledge-payment association.
The Transaction pattern is asynchronous — the API accepts your payload and returns success without immediately producing a visible Contact or Gift record. The actual creation happens during the nightly batch run.
Pattern 2: Direct create
The direct endpoints —POST /api/Contact and POST /api/Gift — create records synchronously and bypass the matching pipeline. The record appears immediately in the UI with the exact fields you provided.
This pattern is appropriate when you have already independently verified that no duplicate exists (for example, you have a verified Virtuous Contact ID for the donor and you are explicitly creating a related record on that Contact). It is not appropriate for general donor data sync from external systems — partners using direct create without their own matching logic routinely produce duplicate Contacts.
The Transactions concept page goes into the transaction pattern in detail, including the nightly batch lifecycle, the import-review workflow, and how to detect transactions that failed to match a Contact.
How to read data out of Virtuous
Reading data uses three patterns, each suited to different scenarios:- Get by ID —
GET /api/Contact/{contactId},GET /api/Gift/{giftId}, etc. Returns one record by its primary key. Used when you already know the Virtuous ID — typically because you stored it on a previous sync. - Query with filters —
POST /api/Contact/Query,POST /api/Gift/Query, etc. Returns a paginated, filtered list. Used for incremental sync (e.g., “all Contacts modified after timestamp X”) and bulk export. See Pagination and Filtering. - Look up by external reference —
GET /api/Contact/ByReference/{referenceId}andPOST /api/Contact/Find. Used to translate an external system’s identifier (a Stripe customer ID, an Eventbrite registration email) into a Virtuous Contact ID. Critical for sync workflows that need to find the Virtuous record corresponding to an external one.
Resource identifiers
Every resource has a numericid field as its primary key. IDs are unique within an organization but not unique across organizations — a Contact with id: 4821 in one nonprofit’s Virtuous instance is unrelated to a Contact with id: 4821 in another nonprofit’s instance.
Partner integrations that serve multiple nonprofit customers must scope stored Virtuous IDs by customer. Storing just (contactId: 4821) in your database is not enough — you need (customerId: "acme-org", contactId: 4821) to disambiguate.
Some resources also carry external reference identifiers — see the Relationships and IDs concept page for how contactReferences and transactionSource/transactionId work as the bridge between Virtuous IDs and your platform’s IDs.
Where to go next
The remaining Core Concepts pages cover each major area in detail. Read them in order if you are new to Virtuous; jump to the specific page if you are building a focused integration.Contacts
The Contact / ContactIndividual / ContactAddress hierarchy and how to avoid duplicates.
Donations / Gifts
Gift records, gift types, designations, and the relationship to Projects and Campaigns.
Transactions
The recommended pattern for partner data import — how the holding state and nightly batch work.
Funds, Campaigns, and Designations
How money flows from a Gift through Designations to fund Projects under Campaigns.
Custom Fields
How nonprofits extend the data model and how partners read and write custom field values.
Relationships and IDs
Foreign keys, external reference IDs, and how to bridge your platform’s IDs with Virtuous’s.
Statuses and Lifecycle States
Active, archived, private, and deceased flags — what they mean and when to check them.