Skip to main content
The Volunteer API is heavily read-oriented. Of 24 endpoints, only 4 support writes (one upsert for Users, four endpoints for Groups, and two for Projects). Most operations a partner integration might want to do — recording participations, submitting Form responses, scheduling Project Dates, awarding Certificates — are not exposed in the API. This page is the canonical reference for those gaps. It enumerates what the API doesn’t support, organized by resource, with the workarounds where they exist and the escalation paths where they don’t. The audience is integration architects setting expectations during onboarding, support engineers triaging “can we do X?” questions, and engineers planning workflows. If you have a partner integration in design or production, treat this as the explicit “what to coordinate with the customer’s admin team on” list.

The four write endpoints

For reference, the only write surface in the API:
EndpointMethodWhat it does
/usersPOSTCreate or update a User (upsert by email)
/projectsPOSTCreate a Project with its schedule
/projects/{id}PUTReplace a Project (with its schedule)
/groupsPOSTCreate a Group
/groups/{id}PUTUpdate a Group’s metadata + members
/groups/{id}DELETEDelete a Group
/groups/{id}/membersPUTReplace a Group’s member list
That’s it. Everything else — every other resource family and every other write operation — happens through the VOMO admin UI or through a separate admin-team coordination.

Participation: not exposed

The most-requested missing capability. Participations are the central record of “this volunteer attended this Project Date” — and they’re entirely managed in the VOMO admin UI.
What partners often wantStatus
Create a Participation (sign someone up programmatically)Not exposed
Update a Participation’s check-in / check-out timesNot exposed
Modify the recorded hours for a ParticipationNot exposed
Mark a Participation as verifiedNot exposed
Cancel or delete a ParticipationNot exposed
Bulk-import historical ParticipationsNot exposed via API

What partners can do instead

GoalWorkaround
Sign volunteers up programmaticallyCoordinate with VOMO admin team; typically a CSV import
Record completed volunteer hoursSame — admin team workflow
Display participation dataRead via GET /users/{id} (embedded in UserDetailResource.participations) and GET /projects/date/{id} (embedded participants)
Detect new participations for change-detection workflowsPoll the User detail or Project Date endpoints; compare against your last-known snapshot

Why this matters for architecture

Many partner integrations imagine a flow like:
External event → Partner API → POST /participations (doesn't exist!)
The right flow is typically:
External event → Partner API → record locally → coordinate with admin team for batch import
Or, for workflows where pure VOMO authority isn’t required:
External event → Partner API → record locally → external system is authoritative; VOMO is sync target only via CSV
Set this expectation with customers during integration design. The API’s lack of Participation writes is the single biggest architectural constraint for most Volunteer integrations.

Project Date: not independently managed

Project Dates exist only as part of a Project. You cannot:
What partners often wantStatus
Create a Project Date independentlyNot exposeddates is required at Project create/update
Modify a Project Date’s start/end times in isolationNot exposed — must PUT the full Project
Cancel a single Project DateNot exposed — must remove from Project’s dates array via PUT
List all Project Dates across all ProjectsNot exposed — no top-level /project-dates endpoint
Get a Project Date by project_id + dateNot exposed — only by Project Date id

What partners can do

GoalWorkaround
Add a new Project Date to a recurring ProjectGET-then-PUT on /projects/{id} with extended dates array
Remove a Project DateGET-then-PUT on /projects/{id} with the Date omitted from dates
Read today’s Project DatesUse GET /projects/today
Read a specific Project Date with participantsUse GET /projects/date/{id}
Read a Project’s full scheduleUse GET /projects/{id}all_dates is embedded
See Create or Update a Project: Adjust a Project’s schedule for the schedule-modification pattern.

The “can’t have zero dates” constraint

Because dates is required on PUT /projects/{id}, you can’t remove all Project Dates from a Project via the API. Implications:
  • “Cancel all future shifts” requires either keeping a placeholder date or deleting the Project (which requires admin UI)
  • Programmatic cleanup of expired schedules has friction

Form submission: not exposed

Form Completions are read-only via the API. Partners cannot:
What partners often wantStatus
Submit a Form on behalf of a userNot exposed
Update an existing Form Completion’s responsesNot exposed
Delete a Form CompletionNot exposed
Modify a Form’s fields or optionsNot exposed
Create a new FormNot exposed
Archive or delete a FormNot exposed

What partners can do

GoalWorkaround
Capture form data externally (e.g., on partner’s signup page)Store externally; coordinate with admin team for periodic VOMO sync
Display submitted Form CompletionsRead via GET /forms/{id}/completions and join with Form field definitions
Detect new Form submissionsIncremental polling with created_after filter
Aggregate Form responses for reportingPull all completions, aggregate client-side or push to a BI tool

Certificates: read-only

Certificates have a single GET /certificates endpoint and nothing else:
What partners often wantStatus
Award a Certificate to a userNot exposed
Revoke a Certificate from a userNot exposed
Create a new Certificate typeNot exposed
Modify a Certificate’s requirements or expirationNot exposed
Delete a Certificate typeNot exposed

What partners can do

GoalWorkaround
Display Certificates required for a ProjectRead via GET /projects/{id} — Certificates listed on the Project
Display Certificates a user has earnedRead via GET /users/{id} (the exact field shape for earned certificates is not formally specified in the spec)
Track Certificate expiration for renewal workflowsCalculate from expiration_in_months on Certificate definition + earned date from User detail
Sync Certificate types to an external compliance systemRead via GET /certificates periodically
For workflows that need to award certificates programmatically (e.g., after a user completes external training), coordinate with the customer’s admin team — typically a CSV import or admin-UI workflow.

Organizations: read-only

Organizations are entirely admin-UI-managed:
What partners often wantStatus
Create a new OrganizationNot exposed
Modify an Organization’s metadataNot exposed
Change parent-child relationshipsNot exposed
Delete an OrganizationNot exposed
Update Organization monikers, addresses, or contact infoNot exposed

What partners can do

GoalWorkaround
Display Organization family structureRead via GET /organizations and GET /organizations/{id}
Route data based on which org within the familyRead the organization_slug from Project / Campaign records
Display custom monikers in your UICache from GET /organizations/{id}
For workflows that need to provision new child organizations (e.g., expanding a customer’s family programmatically), coordinate with VOMO support.

Campaigns: read-only

Campaigns are entirely admin-UI-managed:
What partners often wantStatus
Create a new CampaignNot exposed
Modify a Campaign’s metadataNot exposed
Add a Project to a CampaignNot exposed — Project ↔ Campaign attachment is admin-UI-managed
Remove a Project from a CampaignNot exposed
Delete a CampaignNot exposed

What partners can do

GoalWorkaround
Display Campaign list and metadataRead via GET /campaigns and GET /campaigns/{id}
Filter Projects by Campaign membershipRead Projects, filter by the campaigns array on each
Report on Campaign performanceAggregate Project-level data into Campaign-level metrics
For partner integrations that want to create programmatic per-customer Campaigns, coordinate with VOMO support.

Users: limited write surface

Users have one write endpoint (POST /users) — an upsert by email. Beyond that:
What partners often wantStatus
Update a User by ID (without their email)Not exposed — upsert matches on email only
Delete a UserNot exposed
Merge two duplicate User recordsNot exposed
Change a User’s emailNot exposed — would create duplicate per the email-change problem
Restore a soft-deleted UserNot exposed
Modify a User’s user_status (e.g., verify, ban)Not exposed — managed in admin UI
Modify a User’s membership_status or membership_roleNot exposed
Bulk-upsert many Users in one requestNot exposed — one User per request

What partners can do

GoalWorkaround
Create or update a User from external dataUse POST /users upsert
Detect create vs. updateInspect 200 (updated) vs 201 (created) response
Find a User by emailUse GET /users?email_like=X with exact-equality filter
Read User detail including participationsUse GET /users/{id}
Bulk importIterate with throttling — one request per User
See Create or Update a User for the upsert details and the email-change problem.

Groups: full CRUD (the exception)

Groups are the one resource family with full write support:
CapabilityStatus
CreatePOST /groups
ReadGET /groups, GET /groups/{id}
UpdatePUT /groups/{id}
DeleteDELETE /groups/{id}
Manage membersPUT /groups/{id}/members
If your integration needs programmatic organization of users into stable collections, Groups are where you do it. See Manage Groups and Members.

Other notable missing capabilities

No webhooks

The Volunteer API has no webhook surface. Partner integrations that need to react to changes in VOMO data must poll. See Polling and Sync for the patterns.

No bulk operations

Every write is a single-resource operation. There’s no:
  • Bulk User upsert (one body with many users)
  • Bulk Group create
  • Bulk member-add across multiple Groups
  • Bulk operation for any other resource
For partner integrations operating at scale, this means throttled iteration — see Rate Limits.

No PATCH (partial update)

All updates are full-record replacement via PUT. The implications:
ImplicationWhat it means
GET-then-PUT for any partial updateCost of one read per update
Easy to accidentally clear fields by omissionThe GET-then-PUT pattern protects against this
No optimistic concurrencyNo If-Match header or ETag mechanism
Race conditions possibleTwo clients PUT-ing the same Group can clobber each other’s changes
For high-concurrency workflows, consider locking or coordination at the partner integration level.

No conditional requests

The API doesn’t support If-Modified-Since or ETag-based conditional reads. Every GET re-fetches the full record.

No field-level filtering

The API doesn’t support ?fields=name,email style sparse-fieldset queries. You always get the full resource shape.

No GraphQL or batch query endpoint

Each query is a separate HTTP request. There’s no way to ask “give me these 10 users with these 5 fields each” in one request — you make 10 requests (or one large list query and then filter).

Escalation paths

When a partner integration needs something the API doesn’t support, the path forward depends on the type of need:

For one-time data operations

OperationEscalation
Bulk import historical ParticipationsCustomer’s admin team — typically CSV import
Bulk award Certificates to past completersSame
One-time roster migration from another platformSame
Initial setup of Forms / Campaigns / CertificatesAdmin UI by customer

For ongoing programmatic needs

OperationEscalation
Programmatic Participation recordingCoordinate with VOMO product team about future API support
Programmatic Project Date schedulingSame
Programmatic Form submissionSame
Programmatic Certificate awardingSame
These are common partner requests. If your integration’s design depends on one of them, raise it with VOMO product/integration leads early — the API surface evolves over time, and feedback from real integration needs influences what gets added.

For VOMO product / API issues

IssueEscalation
API returning unexpected errorsVOMO support
Documentation gapsVOMO docs team (or this documentation’s maintainers)
Customer-specific data issuesVOMO support + customer’s admin team
Token / authentication problemsVOMO support

What this means for integration design

A few principles to bake into integration architecture given these limitations:

1. Treat VOMO as a read source for most data

For most partner integrations, VOMO is an information source — your integration reads from it and pushes that data into other systems. Treat external systems (CRMs, BI tools, accounting) as the destinations, with VOMO as the upstream.

2. Use Users + Groups as your primary write surface

The two write-capable resource families (Users via upsert, Groups via full CRUD) are where most “push into VOMO” workflows should focus. If your integration concept depends on writing to other resources, redesign or coordinate with admin team.

3. Build expectations into customer onboarding

The most common customer disappointment is “I want my external system to automatically sign up volunteers for shifts” — which isn’t possible via API. Set this expectation explicitly during onboarding so the customer understands they (or their admin team) handle scheduling in VOMO, while your integration handles the data flow around it.

4. Polling is fine — design for it

The lack of webhooks isn’t a deal-breaker; many production integrations operate fine on polling. Build polling architecture into your design from the start rather than retrofitting it. See Polling and Sync.

5. Cache aggressively

The lack of conditional requests, the small page size, and the read-heavy nature of typical workflows all argue for aggressive caching. Cache:
  • Form field definitions (change rarely)
  • Certificate definitions (change rarely)
  • Organization data (changes rarely)
  • Project schedules (between updates)
  • User detail (between known changes)
See API Performance Tips.

6. Document gaps in your own partner docs

If you’re building a partner integration that surfaces VOMO data to end customers, document the same limitations in your own product docs. Customers will ask “why can’t I do X?” — and the answer is often “VOMO’s API doesn’t expose that,” not a limitation of your product.

A self-check before promising features

Before promising a customer that your integration can do something, walk through this:
  • Can the operation be done via one of the four write endpoints?
  • If not, can the data be captured externally and synced separately?
  • If a sync is needed, does the customer’s admin team need to participate?
  • What’s the freshness expectation, and does polling meet it?
  • What’s the failure mode if VOMO is unavailable or rate-limited?
This checklist catches most “we can’t actually do that” surprises before they reach the customer.

Where to go next

Polling and Sync

The change-detection patterns that compensate for the lack of webhooks.

The Volunteer Data Model

The full data model — useful for understanding what’s read-only vs. write-capable.

API Performance Tips

The caching patterns that make read-heavy workflows scale.

Sync Architecture Patterns

The broader architectural patterns for read-source-and-sync designs.
Last modified on May 22, 2026