Skip to main content
A Campaign in Raise is a top-level fundraising effort — an annual appeal, a capital campaign, a specific initiative. It owns the Segments and Forms that produce donations and tracks aggregate metrics like total raised, donor count, and conversion rate against configured goals. Unlike the donation submission and form-management surfaces, the Campaign resource has full CRUD plus several specialized operations. Partner integrations that need to read or manage Campaign-level data have a solid endpoint surface to work with.

The Campaign record

FieldTypeDescription
idintegerThe Raise primary key. Immutable after creation.
namestringDisplay name of the campaign.
descriptionstringFree-text description.
startDatestringWhen the campaign begins.
endDatestringWhen the campaign ends.
durationstringComputed display string for the campaign’s duration.
createdDateTimestringWhen the campaign was created in Raise.
modifiedDateTimestringWhen any field on the campaign was last changed.

Sync configuration

FieldTypeDescription
canSyncbooleanWhether the campaign is configured to sync to downstream products (e.g., CRM+).
crmKeystringThe campaign’s primary key in the external CRM.
crmKeyUrlsobjectA map of integration types to URL info for linking to the campaign in each external system.
applySegmentToRecurringGiftsbooleanWhether segment attribution applies to recurring gifts generated by this campaign.
The canSync flag is particularly important for customers running CRM+ alongside Raise — it controls whether the campaign and its gifts surface in CRM+ at all. See How Raise Data Flows to CRM+ for details.

Goal tracking

FieldTypeDescription
givingGoalnumberThe dollar amount the campaign aims to raise (in base currency).
givingGoalFormattedstringThe goal pre-formatted for display.
hasGivingGoalbooleanWhether a giving goal is configured.
raisedAmountstringThe amount raised against the goal.
raisedPercentagenumberThe percentage of the goal achieved (0–100).
totalGiftGoalintegerThe target count of gifts.
hasTotalGiftGoalbooleanWhether a gift-count goal is configured.
totalGiftsintegerThe actual count of gifts received.
totalGiftsPercentagenumberThe percentage of the gift-count goal achieved.
totalDonorsintegerThe count of distinct donors who have given.
averageGiftGoalnumberThe target average gift amount.
averageGiftGoalFormattedstringThe target pre-formatted for display.
hasAverageGiftGoalbooleanWhether an average-gift goal is configured.
averageGiftAmountstringThe actual average gift amount, formatted.
totalVisitorsintegerThe count of unique visitors to the campaign’s forms.
conversionRatestringThe visitor-to-donor conversion rate as a percentage string.
The goal tracking is comprehensive — partner integrations doing campaign-progress reporting have direct access to the same metrics the customer sees in the Raise admin UI without needing to compute them client-side.

Reading Campaigns

PatternEndpointUse
List allGET /api/Campaign/listPaginated list of all campaigns
Query by filterPOST /api/Campaign/queryAdvanced filtering — see Pagination and Filtering
Get by IDGET /api/Campaign/{id}Single campaign with full detail
The list endpoint uses the standard Filter, Skip, Take, SortBy, Descending, IncludeDetails parameters described in Pagination and Filtering.

Reading campaigns for analytics

For partner integrations building campaign-progress dashboards, the goal-tracking fields on CampaignModel give you everything you need in a single call per campaign:
JavaScript
async function getCampaignProgress(campaignId) {
  const response = await fetch(
    `https://prod-api.raisedonors.com/api/Campaign/${campaignId}`,
    { headers: { Authorization: `Bearer ${process.env.RAISE_API_TOKEN}` } }
  );
  const campaign = await response.json();

  return {
    name: campaign.name,
    raisedAmount: campaign.raisedAmount,
    raisedPercentage: campaign.raisedPercentage,
    totalGifts: campaign.totalGifts,
    totalGiftsPercentage: campaign.totalGiftsPercentage,
    totalDonors: campaign.totalDonors,
    conversionRate: campaign.conversionRate,
  };
}
No need to query Gifts and aggregate them yourself — the campaign record carries the rollup.

Creating and updating Campaigns

Create

cURL
curl -X POST https://prod-api.raisedonors.com/api/Campaign \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "2025 Annual Appeal",
    "description": "Year-end fundraising campaign",
    "startDate": "2025-01-01",
    "endDate": "2025-12-31",
    "givingGoal": 100000,
    "totalGiftGoal": 500,
    "canSync": true
  }'
A successful create returns the new Campaign record with its assigned id.

Update

PUT /api/Campaign/{id} updates an existing campaign. Send the full record:
cURL
curl -X PUT https://prod-api.raisedonors.com/api/Campaign/5678 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 5678,
    "name": "2025 Annual Appeal - Updated",
    "description": "Year-end fundraising campaign with extended deadline",
    "startDate": "2025-01-01",
    "endDate": "2026-01-31",
    "givingGoal": 150000,
    "canSync": true
  }'
The PUT semantics are documented as full-replace — send every field you want to retain. Unlike the Donor endpoint, the Campaign endpoint doesn’t expose a PATCH variant in the spec, so partial-update workflows need to GET-then-PUT.

Delete

cURL
curl -X DELETE https://prod-api.raisedonors.com/api/Campaign/5678 \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Deleting a Campaign that has dependent Segments, Forms, or Gifts may be blocked by referential integrity. Use the dependency-count endpoint to check before attempting deletion — see Checking dependencies below.

Special operations

Toggle sync

PUT /api/Campaign/{campaignId}/toggle-sync enables or disables the campaign’s CRM sync without requiring a full update:
cURL
curl -X PUT https://prod-api.raisedonors.com/api/Campaign/5678/toggle-sync \
  -H "Authorization: Bearer YOUR_API_TOKEN"
This is the safer way to flip canSync because it’s a single-purpose operation — no risk of inadvertently changing other fields. Use it whenever the customer needs to pause or resume sync for a specific campaign. When sync is disabled (canSync: false):
  • New gifts created against this campaign continue to flow into Raise normally.
  • Those gifts do not propagate to CRM+ via the platform sync.
  • Existing gifts already synced to CRM+ remain there — toggle-sync doesn’t retroactively remove records.
When sync is re-enabled, the platform sync resumes for new gifts. Gifts that occurred during the disabled window are not automatically backfilled — coordinate with the customer’s admin team if backfill is needed.

Replace

PUT /api/Campaign/replace migrates dependencies (Segments, Forms, Gifts) from one campaign to another:
cURL
curl -X PUT https://prod-api.raisedonors.com/api/Campaign/replace \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceCampaignId": 5678,
    "targetCampaignId": 9012
  }'
Useful for campaign restructuring — when the customer realizes mid-year that several Segments belong under a different Campaign than originally configured, replace moves them in a single atomic operation. After the replace completes, the source Campaign typically has no dependencies left and can be safely deleted.
Confirm the exact request body shape for PUT /api/Campaign/replace against the live API. The spec’s endpoint description says “Replace a campaign with another campaign for its dependencies” but the body structure for source/target identification isn’t detailed in the schema.

Checking dependencies

cURL
curl https://prod-api.raisedonors.com/api/Campaign/5678/dependency-count \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Returns counts of how many Segments, Forms, Gifts, and other resources depend on this Campaign. Use this before attempting deletion to avoid blocked-delete errors, and to surface a clear “this campaign has N gifts attached — are you sure you want to delete it?” warning in your integration’s UI.

Campaign lifecycle in practice

A typical Campaign goes through a small number of states over its lifetime:
StateWhat it meansIndicators
ActiveThe campaign is open for donationsCurrent date between startDate and endDate; forms accept submissions
ClosedThe campaign’s giving window has endedCurrent date after endDate; forms may still be visible but typically redirected
ArchivedThe campaign is no longer in active use(No explicit field — customers typically delete or stop syncing)
The Raise spec doesn’t expose a separate isArchived flag on Campaigns the way it does on Donors. Campaigns past their endDate continue to exist with their historical data; the customer chooses whether to delete them (via the API or admin UI) or leave them in place for historical reporting.

Common patterns

Campaign-by-name lookup

A frequent partner pattern: looking up a Campaign by name rather than ID. The Raise API doesn’t expose a dedicated lookup-by-name endpoint, but the Query endpoint handles it:
JavaScript
async function findCampaignByName(name) {
  const response = await fetch(
    'https://prod-api.raisedonors.com/api/Campaign/query',
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.RAISE_API_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        skip: 0,
        take: 1,
        // Use the structured filter — see Pagination and Filtering for the integer operator discovery
        groups: [
          {
            conditions: [
              { parameter: 'name', operator: 0 /* equals — discover via QueryOptions */, value: name },
            ],
          },
        ],
      }),
    }
  );
  const page = await response.json();
  return page.items[0] || null;
}
The integer operator value for “equals” needs to be discovered through GET /api/Query/options/{queryType} — see Pagination and Filtering: Discovering query options.

Active-campaigns cache

Most partner integrations need a current list of active campaigns. Cache the result at startup and refresh on a slow cadence:
JavaScript
class CampaignCache {
  constructor(token) {
    this.token = token;
    this.campaigns = new Map();
    this.lastRefresh = 0;
    this.ttl = 60 * 60 * 1000; // 1 hour
  }

  async getAll() {
    if (Date.now() - this.lastRefresh < this.ttl && this.campaigns.size > 0) {
      return Array.from(this.campaigns.values());
    }
    await this.refresh();
    return Array.from(this.campaigns.values());
  }

  async refresh() {
    const params = new URLSearchParams({ Take: '1000', SortBy: 'createddatetime' });
    const response = await fetch(
      `https://prod-api.raisedonors.com/api/Campaign/list?${params}`,
      { headers: { Authorization: `Bearer ${this.token}` } }
    );
    const page = await response.json();

    this.campaigns.clear();
    for (const campaign of page.items) {
      this.campaigns.set(campaign.id, campaign);
    }
    this.lastRefresh = Date.now();
  }
}
A 1-hour TTL is reasonable for most integrations — Campaigns don’t change minute to minute.

Where to go next

Recurring Gifts

The other core resource — recurring donation schedules.

How Raise Data Flows to CRM+

The platform-level sync controlled by the canSync flag.

Donation Forms

The forms that sit under Campaigns and Segments.

Statuses and Lifecycle States

The lifecycle states that apply to Campaigns, Gifts, and RecurringGifts.
Last modified on May 20, 2026