Skip to main content
A Campaign in the Volunteer API represents a longer-running initiative that spans multiple Projects. Where Projects represent specific volunteer opportunities (“Saturday Food Bank Shift”), Campaigns represent the broader effort that ties multiple opportunities together (“Summer Outreach 2025”, “Holiday Giving Drive”, “Earth Day Initiative”). For partner integrations, Campaigns are the natural reporting and attribution dimension — “how did the Summer Outreach campaign perform?”, “show me all Projects in the Holiday Drive”. They’re read-only from the API; Campaign creation and management happens in the VOMO admin UI.

The two endpoints

There are no write endpoints for Campaigns. The two endpoints are sufficient for the read-oriented integration patterns Campaigns support.
⚠️ Spec gap (audit #4): Both Campaign endpoints have empty schema: {} in the spec — the response shape is only documented through inline examples. The CampaignResource schema component exists but isn’t referenced from either endpoint. Build parsers from actual response shapes.

The Campaign resource

The CampaignResource schema documents these fields:
⚠️ Spec gap (audit #13): CampaignResource.description reads "A VOMO Project" — a copy-paste error. The schema describes a Campaign, not a Project. The description will be corrected in a future spec revision.

About the campaign_name field

The campaign_name field name is unusual — it includes a redundant resource-type prefix. The audit flagged this (#10) as inconsistent with the standard convention of plain name used in other Virtuous APIs. For partner integrations:
JavaScript
Mapping campaign_name to name in your integration’s internal representation produces consistency across CRM+, Raise, and Volunteer Campaign records.

Organization attribution

Campaigns belong to specific organizations within the family. The organization and organization_slug fields identify which: There’s no organization_id field documented on Campaigns (unlike Projects, which expose all three: organization, organization_id, organization_slug). Use organization_slug as the identifier for org-based logic.

Listing campaigns

cURL

Available filters

These mirror the filter set on /projects (minus the Project-specific date filters). The org_slug parameter is the canonical way to filter Campaigns to specific organizations within the family.

Common list patterns

Campaigns for a specific organization:
JavaScript
Campaigns for multiple child organizations:
JavaScript
Recently-created campaigns:
JavaScript
Find a Campaign by partial name (interactive search):
JavaScript

Fetching a single campaign

cURL
Returns the CampaignResource wrapped in data:
JavaScript
⚠️ Spec gap (audit #4): GET /campaigns/{id} has empty schema: {} in the spec. The response likely includes additional fields beyond what’s in CampaignResource (such as an embedded Project list), but the exact extended shape isn’t formally specified.

Campaigns and Projects

Campaigns group Projects. The relationship is captured on the Project side — each Project’s ProjectResource includes a campaigns array showing which Campaigns it belongs to:
A Project can belong to multiple Campaigns (an outreach event can be both part of the seasonal “Summer Outreach” Campaign and the issue-focused “Food Security” Campaign).

Finding Projects in a Campaign

Two approaches: The first approach is more reliable:
JavaScript
For partner integrations doing this query frequently, cache the Campaign → Projects mapping rather than re-querying on every request.

Counting volunteers in a Campaign

A common reporting question: “how many people volunteered for this Campaign?”
JavaScript
This is expensive (N+1+M — one Projects query, one Project detail per Project, one Project Date detail per Date). For large Campaigns with many Projects and many Project Dates, consider:
  • Caching the Campaign’s project list (changes infrequently)
  • Caching Project Date participants by date ID (each date’s participants don’t change after the date passes)
  • Doing the aggregation offline as a reconciliation job rather than per-request
See API Performance Tips for the broader pattern.

Common workflows

Campaign performance dashboard

For a “how is Campaign X doing?” dashboard:
JavaScript
Aggregate the Campaign’s Project-level data into Campaign-level metrics. Cache aggressively — these dashboard reads are expensive.

Cross-Campaign comparison

JavaScript
Useful for side-by-side comparisons of similar Campaigns (“how did Summer 2024 compare to Summer 2025?”).

Sync Campaign list to an external system

For partner integrations mirroring Campaigns into an external CRM or reporting tool:
JavaScript
The updated_after filter combined with links.next pagination produces a clean incremental sync. Schedule this daily or hourly depending on the customer’s reporting cadence.

What can’t be done via the API

If partner integrations need to programmatically create or modify Campaigns, coordinate with VOMO’s admin team. The most common request — creating a per-customer Campaign from an external system — typically becomes an admin-team workflow rather than an API workflow. See Understand Write Limitations.

A reference Campaigns client

JavaScript
The campaign_namename normalization is the key transformation — it produces a Campaign object that looks consistent with how other systems represent Campaign records.

Where to go next

Projects and Project Dates

The Projects that Campaigns group together.

Organizations and Org Family

Organizations own Campaigns within the family.

Forms and Form Completions

Forms are typically attached to Projects within Campaigns.

The Volunteer Data Model

The full data model context for Campaigns.
Last modified on May 22, 2026