Skip to main content
When a donor gives a gift in CRM+, that gift is allocated to one or more specific purposes. This page covers the three-layer model that connects a Gift to those purposes: GiftDesignation (the allocation), Project (the destination), and Campaign (the organizing context).

Terminology bridge

If you are coming from another nonprofit platform (Blackbaud Raiser’s Edge, DonorPerfect, Salesforce NPSP, NetSuite), you may know this concept as a “fund.” In Virtuous, the equivalent resource is the Project. The page title uses “Funds” because that is the partner-recognizable term, but every endpoint and field in the API uses Project. The rest of this page uses the Virtuous terminology.

The three-layer model

Each layer answers a different question about a donation:
  • Project answers “what does this gift fund?” — a specific program, initiative, or operational purpose.
  • GiftDesignation answers “how much of this gift goes to that purpose?” — the split. A gift can fund multiple projects with separate amounts.
  • Campaign answers “what fundraising effort is this gift part of?” — the time-bound context for reporting and analysis.

Projects — the funding destination

A Project is a fundable purpose. It has a name, a code, balances, and a set of flags controlling its visibility and behavior. A typical Project record:

Project codes — the partner integration’s anchor

Three fields can identify a Project in API calls: For partner integrations, projectCode is usually the right reference. It is human-readable, it can be configured to match your platform’s identifier for the same fund, and it stays stable even if Virtuous database IDs change in unusual recovery scenarios. The GiftDesignation accepts projectCode directly:

Project lifecycle flags

Four boolean flags determine whether a Project is currently usable for gift designation: Partner integrations submitting gifts should respect isActive — designating to an inactive Project will produce a 400 or 422 error from the API. The defensive pattern is to query for active Projects at integration setup and surface them to your customer for mapping.

Sub-projects

Projects can have a parent-child hierarchy through the parentId field. Sub-projects roll up to their parent for reporting purposes — giving to “Clean Water → Sub-Saharan Africa” is also counted toward “Clean Water” totals. For partner integrations, the hierarchy is mostly transparent — designate to the most specific Project (the sub-project), and Virtuous handles the rollup automatically.

Reading Projects

Three patterns for discovering Projects in your integration: GET /api/Project/{projectId}/Balance returns the current balance and giving totals for a specific Project — useful for displaying progress in a donor portal or partner dashboard.

Campaigns — the organizing context

A Campaign is a time-bound fundraising effort that groups Projects together. “Year-End Giving 2024”, “Capital Campaign Phase II”, “Giving Tuesday 2024” — each is a Campaign that combines one or more Projects toward a unified goal. A typical Campaign record:
Campaigns are referenced indirectly by Gifts — through the Projects in their GiftDesignations. A gift designated to a Project that belongs to “Year-End Giving 2024” is part of that Campaign for reporting purposes.
Campaigns are read-only through the CRM+ API. The API exposes GET /api/Campaign/{campaignId}, POST /api/Campaign/Query, and GET /api/Campaign/QueryOptions — but there is no POST /api/Campaign, no PUT /api/Campaign/{campaignId}, and no DELETE /api/Campaign/{campaignId}.Partners cannot create Campaigns programmatically. If your integration needs a new Campaign, direct the nonprofit administrator to create it in the Virtuous UI under Campaigns, then reference its Projects in your gift submissions.

Campaign steps

Some Campaigns are structured as a sequence of activities or touchpoints (a “campaign plan”). GET /api/Campaign/GetStepsByCampaignId/{campaignId} returns the steps defined for a Campaign. Most partner integrations do not need to interact with campaign steps directly.

GiftDesignations — the allocation

A GiftDesignation records the allocation of a portion of a Gift to a specific Project. Every Gift has at least one designation. The total of all designation amounts must equal the Gift’s amount.

Split donations

A donor giving $500 split across two Projects produces a Gift with two designations:
The API rejects gifts where designation amounts don’t sum to the gift amount — the validation runs synchronously on Gift Transaction submissions and returns a 400 if the totals don’t match.

Single-Project gifts

The far more common case is a single designation for the full gift amount:
If your platform captures a single fund per donation, always submit one designation for the full amount. Do not omit giftDesignations — gifts without designations are rejected.

Reading designations

Designations are also embedded in Gift responses (giftDesignations array on the Gift), so most workflows don’t need to query designations independently.

Segments

A Segment is a related concept worth a brief mention here even though it is not a Project or Campaign. Segments are groupings of Contacts (e.g., “Major Donors”, “Lapsed Givers”, “Board Members”) used for outreach targeting and campaign association. Unlike Projects and Campaigns, Segments are Contact-centric — they answer “who” rather than “what” or “when.” Endpoints: Gifts can carry a segment (or segmentCode) field to associate the gift with a specific Segment for attribution and reporting. Some Campaign workflows use Segments to identify which donors received a particular appeal.

Partner integration patterns

A few common patterns for partner integrations touching this layer of the model:

Pattern 1: Static Project mapping

For partners with a fixed set of fund options (e.g., a peer-to-peer platform where donors choose from a curated list), the cleanest pattern is:
  1. At integration setup, present the customer with the list of active Projects (POST /api/Project/Query filtered to isActive: true).
  2. Store a mapping from your platform’s fund options to Virtuous Project codes.
  3. On each gift, look up the mapping and submit the gift with the appropriate projectCode in giftDesignations.

Pattern 2: Dynamic Project sync

For partners that need full visibility into all Projects (e.g., reporting integrations, accounting reconciliation), sync the full Project list:
  1. Run POST /api/Project/Query with take=1000 and paginate until exhausted.
  2. Filter for isActive and isPublic as needed.
  3. Subscribe to webhooks for Project changes if available, or re-sync periodically.

Pattern 3: Code-as-bridge

For partners working with the customer’s accounting system, use externalAccountingCode as the bridge:
  1. Your accounting integration has GL account codes.
  2. Virtuous Projects are configured with matching externalAccountingCode values.
  3. Submit gifts using the externalAccountingCode as a reference; reconciliation between the two systems happens on that code.

Where to go next

Donations / Gifts

The Gift resource and how designations connect a gift to projects.

Transactions

How designations are resolved during the nightly batch — including code-based lookups.

Custom Fields

Projects have their own custom fields — use them to store partner-specific metadata.

Create a Donation

A working example of recording a Gift with one or more designations.
Last modified on May 21, 2026