Skip to main content
For customers running both Raise and CRM+, donation and donor data flows from Raise into CRM+ through a platform-level sync that lives outside both products’ APIs. Your Raise integration doesn’t call CRM+ directly, and your CRM+ integration doesn’t call Raise directly. This page documents what the sync is, what partners can see and influence from the Raise API, and the patterns for reading data from both products in a single workflow. The audience is partner integration teams that need to understand cross-product behavior — even when their integration only targets one product. Decisions like “should I match this donor by email or by CRM+ Contact ID?” depend on understanding the sync.

What flows where

The sync is one-directional: Raise → CRM+. Three resources have a sync mapping into CRM+: Other Raise resources (Campaigns, Segments, Projects, MotivationCodes) don’t have direct CRM+ equivalents that the sync creates. Campaign attribution does flow with synced Gifts — meaning a synced CRM+ Gift carries enough context to identify the Raise Campaign and Form that produced it.
This page describes the sync as observable from the Raise API. The full sync behavior, including timing guarantees, conflict resolution, and how data conflicts between Raise-originated and CRM+-originated changes are handled, is a platform-level concern that may evolve. The integration patterns on this page are conservative — they assume the sync exists and works, without depending on specific timing or behavior contracts.

Cross-product identifiers: crmKey, crmSecondKey, and crmKeyUrls

Three fields on Raise resources track the linkage to corresponding records in CRM+ (or other external CRMs):

crmKey

The crmKey is the primary identifier of the corresponding record in the external CRM. For a Raise Donor that has been synced to CRM+, crmKey typically holds the CRM+ Contact’s ID. A Raise record that has not yet been synced (or whose sync was disabled) will have crmKey: null. Partner integrations can use the presence or absence of crmKey as a signal:
  • crmKey != null: the record has been synced to at least one external CRM.
  • crmKey == null: the record has not been synced yet, or sync is disabled for the parent Campaign.

crmSecondKey

A secondary identifier on Donors only. Used when the donor needs to be tracked across two distinct external systems, or when an alternative identifier (different from the primary CRM Contact ID) is meaningful.

crmKeyUrls

A map of integration type to CrmUrlInfo records. Each CrmUrlInfo has two fields:
The map is keyed by integration type — for a customer running CRM+, the map typically has one entry under the CRM+ integration key. For a customer running both CRM+ and another CRM, the map can have multiple entries. The url field gives partner integrations a direct hyperlink to the donor’s record in the external CRM. Useful for “view in CRM” links inside the partner’s UI:
JavaScript

Setting crmKey on creation

Several create/update endpoints accept crmKey in the request body — partners can seed the linkage rather than waiting for the sync to populate it:
  • DonorRequestcrmKey field (single key)
  • UpdateDonorPatchRequestcrmKeys field (multiple keys for multi-CRM scenarios)
  • DonorPaymentRequest (the body of POST /api/Raise/give) — crmKey field
  • CampaignRequestcrmKey field
  • RecurringGiftRequestcrmKey field
Setting crmKey on creation is useful when an integration creates a Raise record from data that originated in CRM+: the integration knows the CRM+ Contact ID and can stamp it on the Raise Donor at creation time, avoiding any uncertainty during the sync.

Controlling sync at the Campaign level: canSync

The canSync boolean on a Campaign controls whether that Campaign’s data flows to CRM+. When canSync: true, Gifts produced under the campaign sync as expected; when canSync: false, those Gifts remain in Raise without propagating.

Toggling sync

PUT /api/Campaign/{campaignId}/toggle-sync flips the flag:
cURL
Use this when:
  • The customer needs to pause sync for a specific campaign — e.g., during data cleanup or a CRM+ migration.
  • Test campaigns shouldn’t appear in CRM+ as production data.
  • An integration is performing a bulk import and wants CRM+ sync paused until the import is verified.
See Campaigns: Toggle sync for the full operational detail.

What canSync: false does and doesn’t do

Re-enabling sync (canSync: true) resumes propagation for new gifts but does not automatically backfill the gifts that occurred during the disabled window. For backfill of historical gifts during a sync-disabled period, coordinate with the customer’s admin team — there’s no API endpoint to trigger backfill.

What partner integrations can and can’t do across the two products

The platform-level sync is the only mechanism that moves data between Raise and CRM+. The implications:

Things partner integrations can do

Things partner integrations can’t do


Reconciliation patterns

Partner integrations that read from both Raise and CRM+ — typically reporting tools or unified-view applications — need to reconcile the two data sets. Three patterns work well:

Pattern 1: crmKey as the join key

The most direct approach: use crmKey to match a Raise Donor to its CRM+ Contact. If both records exist, they’re the same entity:
JavaScript
The pattern requires holding tokens for both products. See Authentication and the CRM+ equivalent.

Pattern 2: dual webhook subscription with deduplication

For integrations that want real-time updates from both products, subscribe to webhook events from each separately and deduplicate at the integration level:
JavaScript
The Raise event typically arrives first because it’s created at the time of donation; the CRM+ event arrives after the sync propagates. Integrations that need both should treat the Raise event as the primary signal and the CRM+ event as confirmation that sync completed.

Pattern 3: periodic reconciliation backstop

For high-confidence reconciliation regardless of webhook reliability, run a periodic backstop that queries both sides and reconciles discrepancies:
JavaScript
Allow a reasonable sync-lag window before flagging a “missing in CRM+” gift — depending on the customer’s environment, this could be minutes to hours. Don’t alert on a Raise gift created 5 minutes ago that hasn’t yet appeared in CRM+; do alert on a Raise gift from yesterday that’s still missing.

Timing expectations

The Raise spec does not document timing guarantees for the sync. In practice, partner integrations should plan for:
  • Most gifts appear in CRM+ within seconds to a few minutes after creation in Raise.
  • Occasional gifts may take longer due to processing batching, transient errors, or maintenance windows.
  • Rare gifts may fail to sync entirely if the source data has a problem (malformed donor record, missing required field on the CRM+ side, etc.).
Integrations that need real-time consistency across the two products should either:
  • Use the Raise event as the source of truth and treat CRM+‘s view as eventually consistent, or
  • Implement the periodic-reconciliation backstop (Pattern 3 above) to catch the rare cases where sync doesn’t complete.
Don’t build user-facing features that depend on a CRM+ Gift appearing in real time after a Raise donation — the experience will be unreliable.

When crmKey is missing

A Raise record with crmKey: null could be in any of several states: Partner integrations that read crmKey to drive behavior should not treat its absence as an error. Treat it as “linkage not established yet” and handle gracefully — show a “not yet synced” indicator in the UI rather than a hard failure.

Where to go next

Statuses and Lifecycle States

The lifecycle states across Donors, Gifts, and RecurringGifts that matter for sync reconciliation.

Campaigns

The Campaign resource where canSync and toggle-sync live.

Reconcile Raise with CRM+

The workflow that puts the reconciliation patterns on this page into production.

Sync Architecture Patterns

The broader architectural patterns for sync-aware integration design.
Last modified on May 20, 2026