POST /api/Gift/Query is the Gift counterpart to Contact Query — paginated, filtered retrieval of Gift records. This workflow focuses on the most common partner use of the endpoint: pulling gifts within a date window for reporting, reconciliation with accounting systems, or incremental sync to a data warehouse.
The structure parallels Query Contacts by Filters, but Gifts have date-specific filter patterns and the response contains designation and reference information that’s useful for the partner-canonical reconciliation use case.
Scenario
Your integration needs to retrieve Gifts within a specific date window:- Monthly reporting — every gift in a calendar month for accounting reconciliation.
- Accounting sync — gifts processed since the last sync to push into the customer’s accounting system.
- Custom date range — gifts for a specific campaign window or fiscal period.
Prerequisites
- A valid CRM+ API token — see Authentication.
- Understanding of the filter structure — see Pagination and Filtering.
- The list of valid filter parameters and operators for the organization, retrieved from
GET /api/Gift/QueryOptions.
Step 1: discover valid filter parameters
Gift Query has its own QueryOptions endpoint — independent of the Contact one:cURL
Gift Date, Gift Type, Amount, Receipt Date, Batch, Project, Campaign, and Segment, plus any custom fields configured on the Gift resource.
The spec notes that Gift Query supports sorting by Id, Amount, GiftDate, ReceiptDate, and Batch.
Pattern 1: gifts within a date window
The canonical date-range query — find all gifts withGift Date between two values:
Between operator with value and secondaryValue provides the inclusive bounds. Other operators commonly available for date fields include Is After, Is Before, Is On, and Is After Or On — confirm the exact set via GET /api/Gift/QueryOptions.
Gift Date vs. Receipt Date
CRM+ distinguishes between two date fields on a Gift:| Field | Meaning |
|---|---|
giftDate | The date the donation actually occurred — when the donor gave the gift. |
receiptDate | The date the organization processed and receipted the gift — often the same as giftDate but can differ for backdated entries or mailed checks. |
giftDate is the right filter field. For accounting and tax reconciliation, receiptDate is often more appropriate because it aligns with when the organization recognized the gift in its books.
Pattern 2: incremental gift sync
For continuous sync of new and modified gifts, filter byLast Modified Date rather than Gift Date. This catches both new gifts and edits to existing ones.
JavaScript
Pattern 3: gifts for a specific Project or Campaign
To pull all gifts associated with a particular Project or Campaign — useful for campaign reporting integrations:A Gift is associated with a Campaign indirectly — through the Project(s) in its GiftDesignations, which belong to a Campaign. The
Campaign filter parameter resolves this relationship server-side. See Funds, Campaigns, and Designations for the data-model context.Pattern 4: gifts by amount range
For high-value gift reporting or major-donor identification:Amount descending puts the largest gifts first — useful for major-gift dashboards. The amount filter values are passed as strings in the spec; the live API accepts both string and numeric forms.
Working with the response
ThePOST /api/Gift/Query abbreviated response includes:
| Field | Description |
|---|---|
id | The Gift’s primary key. |
contactId, contactIndividualId | The donor’s IDs. |
giftType, giftDate, amount | The basic gift fields. |
segment, batch | Categorization metadata. |
giftUrl | A URL to view the Gift in the Virtuous UI. |
POST /api/Gift/Query/FullGift instead.
Including transactionSource and transactionId
Gifts that came from your platform’s Transactions carrytransactionSource and transactionId. These appear in the full-gift response. To reconcile a partner-side donation log with the corresponding Virtuous Gifts, use POST /api/Gift/Query/FullGift (or fetch each Gift individually with GET /api/Gift/{giftId} for the small subset you need full detail on).
Reconciliation workflow
A common partner-integration use of date-range queries is monthly reconciliation between the partner’s records and Virtuous. The shape:Define the reconciliation window
Typically a calendar month or the period since the last reconciliation. Use
Gift Date if reconciling against donor-facing reports; use Receipt Date for accounting reconciliation.Query Virtuous for the gifts in that window
Use the pattern from Pattern 1 with
take=1000 to minimize requests.Join against your own records
For each Virtuous Gift, look up the matching record in your platform by
transactionSource + transactionId. Categorize as: matched (present on both sides), Virtuous-only (gift in Virtuous but not on your side), partner-only (gift on your side but not in Virtuous).Investigate discrepancies
Virtuous-only gifts typically indicate manual entries in Virtuous or other integrations. Partner-only gifts indicate sync failures — submitted but never appeared. See Reconcile Failed Syncs.
Performance considerations
take=1000for reconciliation. Each request returns up to 1,000 Gifts and consumes one rate-limit slot. A year’s worth of gifts for a typical mid-sized nonprofit (10,000–50,000 gifts) is 10–50 requests — well within budget.- Sort on indexed fields.
GiftDate,ReceiptDate,Amount,Id, andBatchare indexed per the spec. Custom sort fields may be slow on large result sets. - Filter aggressively. Narrow date ranges produce smaller result sets and faster queries. A query for “all gifts in 2024” is fine; a query for “all gifts ever” should be broken into year-by-year chunks for large databases.
- Use the abbreviated response when possible.
POST /api/Gift/Queryreturns the most useful fields;POST /api/Gift/Query/FullGiftis meaningfully slower per request.
Error handling
The error model is the same as Contact Query — see Query Contacts by Filters for the status codes and remediation. Two Gift-specific cases worth calling out:400on unknown Project or Campaign filter values. The filter accepts a Project or Campaign name — if no Project/Campaign by that name exists, the API returns400rather than an empty result set. Validate the names againstGET /api/Project/QueryandPOST /api/Campaign/Querybefore constructing the filter.- Date format mismatches. Date filter values are typically
YYYY-MM-DDforGift DateandReceipt Date.Last Modified Dateis typicallyYYYY-MM-DDTHH:MM:SSZ. Confirm via the response fromGET /api/Gift/QueryOptions.
Where to go next
Query Contacts by Filters
The Contact equivalent — same pattern, different resource.
Reconcile Failed Syncs
Use date-range queries as the foundation for periodic reconciliation between partner and Virtuous records.
Sync External Donations into Virtuous
The write-side architecture that this read pattern reconciles against.
Donations / Gifts
The Gift data model — fields, designations, types, and lifecycle.