Skip to main content
A Gift in CRM+ is a single donation record — one transfer of value from a donor to the organization. Every Gift belongs to exactly one Contact and is allocated to one or more Projects through GiftDesignations. Gifts are the most financially consequential resource in the API: a gift recorded incorrectly produces accounting errors that are hard to reverse. This page covers the Gift resource and its immediate relationships. The recommended patterns for creating gifts from external systems live on the Transactions concept page.

What a Gift represents

A Gift represents the donation event itself — the amount, the date, the gift type, the donor, and what the donation supports. A typical Gift looks like:
{
  "id": 78421,
  "contactId": 4821,
  "giftType": "Cash",
  "giftDate": "2024-12-15",
  "amount": 500.00,
  "currencyCode": "USD",
  "batch": "Year-End-2024",
  "transactionSource": "Stripe",
  "transactionId": "ch_3PXyz123",
  "giftDesignations": [
    {
      "id": 91002,
      "projectId": 311,
      "project": "Clean Water Initiative",
      "amountDesignated": 300.00
    },
    {
      "id": 91003,
      "projectId": 412,
      "project": "Education Programs",
      "amountDesignated": 200.00
    }
  ],
  "createDateTimeUtc": "2024-12-15T14:23:00Z",
  "modifiedDateTimeUtc": "2024-12-15T14:23:00Z"
}
The Gift links to:
  • One Contact (contactId) — the donor.
  • One or more GiftDesignations — the allocation of the gift’s amount to specific Projects.
  • Optionally, one RecurringGift (recurringGiftTransactionId) — if this Gift is a payment on a recurring schedule.
  • Optionally, one Pledge (pledgeTransactionId) — if this Gift is a payment toward a pledge commitment.
  • Optionally, a transaction source pair (transactionSource + transactionId) — the external system’s identifier for this gift, used for idempotency and reconciliation.

Gift types

The giftType field describes what kind of gift was made. The CRM+ spec does not enumerate the valid values, but the live API supports a documented set covering the major donation types:
Gift typeWhat it represents
CashA monetary donation (cash, check, credit card, ACH). The default for most online giving flows.
EFTElectronic Funds Transfer — bank transfers, ACH, wire.
CreditSpecifically credit-card donations, where the organization tracks them separately from other cash.
StockA gift of securities (publicly traded stock, bonds, mutual funds). Recorded at the fair market value on the gift date.
NonCashAn in-kind donation of goods (auction items, food, equipment, services).
OtherAnything that doesn’t fit the standard types.
The exact gift type strings accepted by the live API are not enumerated in the OpenAPI spec — the field is typed as string. The list above reflects the commonly used values. To discover the gift types valid for a specific organization, call GET /api/Gift/NonCashGiftTypes for the non-cash subset, or check with the organization’s administrator for the full enabled list.
For non-cash gifts, additional fields capture the gift’s nature — nonCashGiftType for the specific type (e.g., “Auction Item”), inKindDescription for a free-text description, and inKindValue for the assessed fair value.

GiftDesignations — where the money goes

A Gift always has at least one GiftDesignation. A designation is the allocation of part (or all) of a gift’s amount to a specific Project. If a donor gives 500entirelytoonecause,theGifthasonedesignationfor500 entirely to one cause, the Gift has one designation for 500. If a donor gives 500splitacrosstwocauses,theGifthastwodesignationswhoseamountDesignatedvaluessumto500 split across two causes, the Gift has two designations whose `amountDesignated` values sum to 500.
FieldTypeDescription
idintegerThe unique designation ID.
projectIdintegerThe Project this allocation funds.
projectstringDisplay name of the Project.
projectCodestringOrganization-defined short code for the Project.
externalAccountingCodestringProject’s accounting-system code (used in reconciliation).
amountDesignatednumberThe portion of the gift allocated to this Project.
The sum of all amountDesignated values on a Gift must equal the Gift’s amount. The API enforces this constraint at creation time.
If your platform captures a single Project per donation (the most common case), record the gift with one designation for the full amount. The split-designation feature is most relevant for major-gift workflows and certain peer-to-peer fundraising scenarios.
For deeper coverage of the Project, Campaign, and Designation model, see Funds, Campaigns, and Designations.

Campaigns

A Campaign is a time-bound fundraising effort that groups Projects together (e.g., “Annual Giving 2024”, “Capital Campaign Phase II”). Gifts are associated with a Campaign through their Project designations — the Project belongs to a Campaign, and the Gift inherits that Campaign context.
Campaigns are read-only through the CRM+ API. The API exposes GET /api/Campaign/{campaignId} and POST /api/Campaign/Query, but there is no POST /api/Campaign, no PUT /api/Campaign/{campaignId}, and no DELETE /api/Campaign/{campaignId}. Campaigns are created and managed exclusively in the Virtuous UI. Partner integrations that need to create new Campaigns programmatically must direct the customer to do so manually in Virtuous — the API does not support it today.
This has practical implications for partners: if your integration needs to associate gifts with a specific Campaign, the nonprofit administrator must create the Campaign in Virtuous first, then your integration references it by the Campaign’s projects.

Recurring gifts and pledges

A Gift can be standalone, or it can be a payment on a longer arrangement:
  • RecurringGift — an ongoing schedule (monthly, quarterly, annual). Each successful payment on the schedule becomes a Gift with recurringGiftTransactionId set to the schedule’s ID. The Gift inherits the RecurringGift’s designations by default.
  • Pledge — a commitment to give a specific amount over time (e.g., “$10,000 over four years”). Each payment toward the pledge becomes a Gift with pledgeTransactionId set to the pledge’s ID, and the Gift’s amount is recorded against the pledge balance.
The detailed lifecycles of RecurringGift and Pledge — schedule states, payment-failure handling, write-off processes — are covered separately. For now, what matters is that when a Gift comes from a recurring schedule or a pledge, those linkages must be set at gift-creation time. Creating an orphan Gift without those linkages will not retroactively associate it with the schedule or the pledge. The Transactions concept page describes how the Transaction endpoint’s matching algorithm can automatically associate an incoming Gift with the correct RecurringGift or Pledge when the linkage fields are populated.

Premiums

A GiftPremium is a donor-recognition item given in exchange for a gift (a t-shirt, a book, an event ticket). Premiums are tracked on the Gift so the organization can fulfill them and so the IRS-deductible portion of the gift can be calculated correctly:
{
  "giftPremiums": [
    {
      "id": 11231,
      "premiumId": 42,
      "premium": "Annual Report",
      "quantity": 1
    }
  ]
}
Premiums are organization-defined — GET /api/Premium returns the catalog of premiums available in the organization. Your integration assigns premiums by their premiumId when recording the Gift.

Transaction source and ID

Two fields connect a Gift back to your platform’s record of the same donation:
FieldTypePurpose
transactionSourcestringThe name of your platform — for example, "Stripe", "Eventbrite", "YourPlatformName".
transactionIdstringYour platform’s unique identifier for this specific donation.
Together, transactionSource + transactionId form an external reference that uniquely identifies the donation in your system. This pair is the foundation of two critical patterns:
  • Idempotent gift creation. When you re-submit a gift with the same transactionSource/transactionId pair (e.g., after a retry following a network failure), the Transaction endpoint matches it as a duplicate and does not create a second Gift record.
  • Lookup-by-external-ID. GET /api/Gift/{transactionSource}/{transactionId} retrieves a Virtuous Gift by your platform’s IDs — useful for syncing updates without storing the Virtuous Gift ID in your database.
Always set transactionSource and transactionId on gifts you create from your platform. The cost is one extra field; the benefit is bullet-proof idempotency and a simple lookup path back to the Virtuous record.

Reversals and refunds

Refunding or reversing a gift uses a dedicated endpoint, not a DELETE on the Gift:
  • POST /api/Gift/ReversingTransaction — records a reversing transaction that offsets the original gift. The original Gift remains on the record (for audit purposes); the reversing transaction is a separate, offsetting record.
This is the correct pattern for any partial or full refund triggered by your platform — for example, a Stripe refund event that needs to flow through to Virtuous. Do not attempt to DELETE /api/Gift/{giftId} for refunds; that is not how the financial audit trail works in Virtuous.

Reading gifts

The standard read patterns:
EndpointWhen to use
GET /api/Gift/{giftId}Look up one Gift by its Virtuous ID.
GET /api/Gift/{transactionSource}/{transactionId}Look up one Gift by your platform’s IDs. The cleanest pattern for sync workflows that don’t store the Virtuous ID.
GET /api/Gift/ByContact/{contactId}List all Gifts for a given Contact.
POST /api/Gift/QueryFiltered paginated retrieval — incremental sync by modification date, bulk export, etc. See Pagination and Filtering.
POST /api/Gift/Query/FullGiftSame as Query but returns the complete Gift payload including all designations, premiums, and pledge linkages. Slower; use only when full detail is required.

Field typing

The CRM+ spec types almost every Gift field as string — including amount (which should be number), giftDate (which should be date), exchangeRate (which should be number), and the boolean flags. The live API accepts and returns the correct types, but SDK generators and schema-validation libraries that read the spec literally will produce types that don’t match the actual API behavior. This is a known documentation gap.When sending data, use the natural types: numbers for amounts, ISO 8601 date strings for dates, booleans for flags. When parsing responses, the same fields come back with correct types.

Where to go next

Transactions

The recommended pattern for creating Gifts from external systems with automatic matching.

Funds, Campaigns, and Designations

How GiftDesignations flow to Projects and how Projects fit into Campaigns.

Create a Donation

A working example of recording a Gift end-to-end.

Sync External Donations into Virtuous

The canonical recipe for pushing gifts from your platform into Virtuous via the Transaction endpoint.

Query Donations by Date Range

Pull gifts within a date window for reporting or reconciliation.

Stripe to Virtuous CRM

A complete integration recipe showing Stripe gift events flowing into Virtuous.
Last modified on May 27, 2026