The eight resource families
The eight resource families:
Two patterns to notice from this table:
The central pattern: User ↔ Participation ↔ Project Date
The most important relationship in the model is the Participation triangle: When a volunteer (User) participates in a specific scheduled occurrence (Project Date) of a recurring opportunity (Project), a Participation record is created. The Participation captures:
Participations are how the API answers questions like:
Reading participations
There’s no top-levelGET /participations endpoint. Participations are always returned embedded in another resource’s response:
For partner integrations that need a flat “all participations” view, the typical pattern is:
- List all users via
GET /userswith pagination. - For each user,
GET /users/{id}to get their participations. - Flatten across all users.
Project vs. Project Date
A common source of confusion: the difference between a Project and a Project Date.Project = the template (the “what”)
A Project is the volunteer opportunity itself — what it is, what’s being asked of volunteers, what skills are needed, what the organization wants to accomplish. It’s a long-lived record that persists across many actual occurrences.name, description, organization, address, age_limit, privacy, categories, and so on.
Project Date = the specific occurrence (the “when”)
A Project Date is one specific scheduled occurrence of a Project. The same Project can have dozens or hundreds of Project Dates over its lifetime.id, starts_at, ends_at, participant_count, and the embedded participants for that date.
In the API
⚠️ Spec gap (audit #34): The endpoint
GET /projects/date/{id} uses a verb-like singular noun (date) in the path, which is inconsistent with REST conventions. The audit recommends renaming to GET /projects/{projectId}/dates/{dateId}. The current path is what works against the live API today; the alternative path may exist in a future v2.Why this matters for integrations
A common bug: querying/projects/{id} expecting to get the participants for an upcoming shift, then being surprised that it returns the template’s metadata instead. The participants are on the Project Date, not the Project.
Organization hierarchy: the “organization family”
Organizations in VOMO can have parent-child relationships. The customer’s primary Organization may have children — sub-organizations like local chapters, regional offices, or affiliated nonprofits — and may itself be a child of a larger umbrella organization.What this enables
- A single API token can be scoped to access the parent organization and its children.
- Reports and aggregations span the full organization family by default.
- Projects, Campaigns, and Groups are owned by specific organizations within the family.
What the API exposes
Per-resource organization attribution
Most resources track which organization in the family they belong to:
When the partner integration is reading data, the attribution lets them route or filter records to the right organization within the family.
Forms: data-collection attached to Projects
Forms in VOMO are data-collection templates — waivers, signups, profile fields, application questions. Volunteers complete Forms; the completion is captured as a Form Completion. The relationships:Where Forms live
Forms are attached to Projects in the admin UI; the partner integration reads them through the endpoints above. Common use cases include waivers (signed once per volunteer), event-specific signups (additional info beyond standard Project signup), and post-event surveys.
Form types
Theform_type field on FormResource has documented enum values, though the audit (#54) flags that only "PROJECT" is documented and other types likely exist.
Certificates: training and achievements
Certificates represent training credentials, badges, or other achievements that volunteers earn. Common uses include:- Required safety training (e.g., food handler certification for food bank volunteers)
- Background check completion
- Specialized role qualifications (e.g., team leader training)
- Completion badges for milestone hours
⚠️ Spec gap (audit #14): The same resource is referred to as “certificate”, “certification”, and “certificates” in different places in the spec — the path is
/certificates, the tag is Certifications, the operationId is listCertifications, and the schema is CertificateResource. The naming will be reconciled in a future spec revision. For partner integrations today, use the path (/certificates) and the schema name (CertificateResource) as your reference points.GET /users/{id}) typically includes earned certificates alongside other user data.
Groups: cross-cutting User collections
Groups in VOMO organize Users into collections — teams, affinity groups, chapter members, etc. Unlike Projects (which represent opportunities), Groups represent stable collections of people that persist independent of specific events. The relationships:
Groups have the most write-heavy surface of any Volunteer resource:
This makes Groups the canonical “build a volunteer team programmatically” resource. Common patterns include:
- Syncing external team rosters into VOMO Groups
- Building Groups based on participation criteria (e.g., “active volunteers in 2024”)
- Creating event-specific Groups for managing rosters
Campaigns: longer-running initiatives
Campaigns group multiple related Projects under a single umbrella initiative. They represent the customer’s longer-term goals or themes:
Campaigns are read-only from the API — they’re managed in the VOMO admin UI. Partner integrations use them for reporting and attribution (“how is the Summer Outreach campaign performing?”).
⚠️ Spec gap (audit #4, #13): The Campaign endpoints have empty
schema: {} in the spec, and CampaignResource description erroneously reads “A VOMO Project.” Build parsers from actual response shapes.What’s NOT in the API
Several resource types that exist in VOMO but aren’t currently exposed in the API:
For partner integrations needing to record participations programmatically, coordinate with VOMO’s admin team for alternative paths — typically through Group management or scheduled imports.
See Understand Write Limitations for the complete picture.
ID stability and matching
Across the API, several patterns govern how IDs work:
User matching for upsert (
POST /users) is done by email — submitting a user with an existing email updates that user; submitting with a new email creates a new one. See Users: upsert behavior.
Cross-API mapping
For partners integrating Volunteer alongside CRM+ or Raise, the conceptual mappings:
Note these are conceptual analogs, not exact matches. A Volunteer User is roughly equivalent to a CRM+ Contact in role (the person record), but the field shapes and write paths differ significantly.
For partner integrations syncing across all three APIs, the typical pattern is:
- Match by email when joining records across APIs
- Treat each API’s records as authoritative for their own domain (User in Volunteer, Contact in CRM+, Donor in Raise)
- Use partner-side mapping tables when the same person needs distinct records in each system
Where to go next
Users
The User resource reference in depth — fields, filters, upsert behavior.
Projects and Project Dates
The Project (template) vs. Project Date (occurrence) distinction in full detail.
Groups
The most write-heavy resource — Group management and members.
Understand Write Limitations
The explicit list of what the API can and can’t do.