When to use this workflow
The three endpoints
The right choice depends on what you have and what you want. The decision tree:
Scenario 1: Get a Project’s full schedule
For a known Project, the most efficient way to get its full schedule isGET /projects/{id} — the response includes all_dates and next_date embedded, so you don’t need separate Project Date fetches.
cURL
What you get without extra calls
all_dates[] includes for each Project Date:
This is enough for calendar views, scheduling displays, and most “show the schedule” workflows. You don’t need to call
GET /projects/date/{id} unless you also need the per-Date participants.
When you need more than all_dates provides
all_dates doesn’t include:
- Per-Date participants (which volunteers signed up for which shift) — requires
GET /projects/date/{id} - Per-Date custom data (if the customer added Project-Date-specific fields)
next_date for “next upcoming shift” displays
The next_date field is convenient for UIs showing “your next opportunity” — it’s the chronologically-nearest future Project Date, pre-computed:
JavaScript
Scenario 2: Daily operational dashboard
For check-in staff or operations dashboards showing “what’s happening today”:cURL
HappeningResource objects — all Project Dates scheduled for today, across all of the organization’s Projects:
What this is good for
Note: today’s Project Dates, not Projects
The response is Project Dates (Happenings), not Projects. A single Project running a morning and afternoon shift today appears as two entries. To roll up to Projects:JavaScript
The cost of “today” + drill-down
The pattern above is N+1 — one/projects/today call plus one /projects/date/{id} per Happening. For organizations with many simultaneous shifts (10-20+ on a given day), this can be expensive. Caching the per-Date detail helps:
JavaScript
Scenario 3: Find Projects with available slots
For partner-built signup interfaces, find Projects with upcoming Dates that have capacity:JavaScript
next_date to avoid fetching all dates for each Project — efficient for the common “find a shift to volunteer for” use case.
For more sophisticated filtering (e.g., “find shifts with at least 5 open spots”), iterate all_dates:
JavaScript
Scenario 4: Get participants for a specific shift
When you need to know who’s signed up for a specific Project Date:cURL
The participants embedded here
Each participant entry has:
This shape includes the Participation data inline (rather than requiring a separate fetch through the User detail). It’s the cleanest path to “who’s signed up for this shift?”
Parsing the participants defensively
JavaScript
hoursreturning as a string ("4.00") instead of integer per audit #40verifiedreturning as0or1integer (treat as boolean)- Missing optional fields
Scenario 5: Build an iCal feed for a Project
A common partner workflow: generate an iCalendar (.ics) feed of a Project’s schedule for the customer’s external calendar systems:
JavaScript
GET /projects/{id} call gives you the full schedule needed for the feed — no per-Date fetches required.
For workflows generating iCal feeds for many Projects simultaneously, cache aggressively — Project schedules change infrequently.
Scenario 6: Multi-Project schedule view
For “all upcoming shifts” displays spanning multiple Projects:JavaScript
JavaScript
Choosing the right endpoint
A summary table for quick decisions:
The pattern is roughly: use the most-embedded endpoint that has what you need, then drill down only when necessary. The Project detail endpoint is the workhorse for most workflows.
What can’t be done via the API
See Understand Write Limitations.
Where to go next
Create or Update a Project
The companion write workflow — modifying the schedule is done by updating the Project.
Inspect Form Completions
The next supplementary workflow.
Projects and Project Dates
The reference page for the field shapes used here.
API Performance Tips
The caching patterns that make multi-Project schedule reads scale.