The data model
The RecurringGift describes the schedule (frequency, amount, designations, start date, status). Each scheduled payment becomes its own Gift record, linked to the RecurringGift via therecurringGiftTransactionId field on the Gift Transaction submission.
Two important consequences of this model:
- The RecurringGift itself is not money. It’s a commitment record. The Gifts that get linked to it represent actual transactions.
- Cancelling a RecurringGift does not delete past Gifts. Cancellation stops new payments from being recorded against the schedule; the historical record of past payments remains.
RecurringGift endpoints
The endpoints available for managing RecurringGifts:Creating a schedule
When a donor signs up for a recurring donation on your platform — a Stripe Subscription, a recurring scheduled donation in your platform’s database — create the corresponding RecurringGift in Virtuous.id — store it on your side alongside your platform’s commitment record.
Required and recommended fields
Frequency values
Pre-flight: the donor’s Contact must exist
POST /api/RecurringGift takes a contactId directly — there is no embedded contact data with matching, unlike POST /api/v2/Gift/Transaction. Resolve or create the donor’s Contact before creating the schedule:
JavaScript
POST /api/v2/Gift/Transaction (which has embedded contact matching) and create the RecurringGift after the Contact appears. The RecurringGift links forward to the next payment; the first payment is one-off in Virtuous.
Linking payments to a schedule
Each time the recurring schedule produces a payment — Stripe charges the subscription, your platform’s recurring billing fires — submit a Gift Transaction withrecurringGiftTransactionId set to the schedule’s transactionId:
JavaScript
transactionIdis the specific payment’s ID — different on every payment of the schedule.recurringGiftTransactionIdis the schedule’s ID — the same value on every payment.
recurringGiftTransactionId to associate the new Gift with the existing schedule. In the UI, the Gift appears in the schedule’s payment history; in reports, the donor’s recurring total reflects the new payment.
Updating a schedule
When the donor changes their recurring amount, switches their designation, or otherwise modifies the schedule, push the change to Virtuous withPUT /api/RecurringGift/{recurringGiftId}.
Follow the same GET-then-PUT pattern as Contact updates (see Update a Contact):
JavaScript
Common update scenarios
Cancelling a schedule
When a donor ends their recurring commitment — actively unsubscribes, cancels in your platform’s portal, or has their payment method fail past the dunning threshold — cancel the schedule in Virtuous:cURL
JavaScript
Cancel endpoint is the right path for cancellation. Do not use PUT /api/RecurringGift/{id} with status: "Cancelled" — the canonical lifecycle transition is via the Cancel endpoint, which sets the cancelDateTimeUtc field and triggers the appropriate audit log entry.
Handling failed payments
When a scheduled payment fails (card expired, insufficient funds, account closed), the partner platform typically enters a dunning state — retrying the payment over several days before giving up. The Virtuous-side handling depends on the eventual outcome:
Importantly: do not submit failed payments as Gifts to Virtuous. A failed payment is not a gift, and recording it produces incorrect totals. Only submit when the payment actually succeeded.
If the customer’s team needs visibility into failed payments — for outreach to the donor — surface them in your integration’s UI or as a separate report, not as Virtuous Gifts.
Reconciliation
Periodic reconciliation between your platform’s recurring schedules and Virtuous catches drift:JavaScript
End-to-end checklist
Before deploying a recurring-donation integration to production, confirm:- RecurringGifts are created with stable
transactionSource+transactionId(the schedule’s ID, not a payment’s ID). - The donor’s Contact is resolved before RecurringGift creation.
- Each recurring payment Gift Transaction includes
recurringGiftTransactionIdlinking back to the schedule. - Schedule updates use
GET-then-PUTwith the full record. - Cancellations use
PUT /api/RecurringGift/Cancel/{id}, not status updates via standard PUT. - Failed payments are not submitted as Gifts.
- Monthly reconciliation runs and surfaces amount/status drift between your platform and Virtuous.
- If your platform supports pause/resume, the chosen Virtuous-side modeling (cancel/recreate vs. suppress-payments) is documented and agreed with the customer.
Where to go next
Stripe to Virtuous CRM
The Stripe-specific recipe that sources recurring schedules from Stripe Subscriptions.
Import Historical Gifts
Backfill historical recurring payment data — each payment as a Gift, linked to the recreated schedule.
Statuses and Lifecycle States
The RecurringGift status field and its lifecycle states.
Reconcile Failed Syncs
Handle drift in recurring schedule state between your platform and Virtuous.