Skip to main content
The connected-calendar API uses Composio-hosted OAuth links. Provider tokens stay with Composio. TheFaithApp stores encrypted connected-account metadata and tenant-bound mappings rather than accepting provider account IDs from the client.

Routes and Ownership

Staff routes use a staff bearer token:
  • /api/events/calendar-connections manages the church organizer connection and requires Events permission.
  • /api/volunteer/calendar-connections manages the authenticated staff member’s own calendar. The staff email must be verified and match a member record in the same church.
Member routes use the authenticated member session:
  • /api/member/calendar-connections
  • /v2/volunteer/calendar-connections
Each route family supports: Member route families also support POST /assignments/{uuid}/respond with response: confirmed or response: declined. A decline requires reason. The assignment must belong to that member and church.

Synchronization Contract

TheFaithApp remains the schedule source. Registered member events and eligible published serving assignments are mirrored to the selected member calendar. Church connections mirror published events and serving plans. Internal notes, safeguarding data, and unrelated calendars are excluded. Stable mappings update an existing provider event when times or locations change, and remove only mapped events after cancellation. Provider event creation uses deterministic IDs or transaction identifiers to avoid duplicate creates after an ambiguous response. Timezones are included explicitly. For native serving RSVPs, a church organizer connection and the member’s active, opted-in serving connection must use the same provider. The member’s verified connected account email is the attendee. Only the mapped organizer event’s response for that attendee can change the assignment. A copied personal appointment uses a TheFaithApp response link instead; deleting or editing it is not an RSVP. Sync is queued after relevant changes and polled by the scheduler. Provider limits and authorization failures appear in connection status and run history. Run the queue worker and Laravel scheduler for synchronization to continue. Disconnect immediately stops local synchronization, attempts to delete mapped provider entries, and revokes upstream access. Failed cleanup can leave entries in the provider and is shown in connection status. Switching a selected calendar removes its mapped entries before creating the new set. Personal appointment copies include a temporary signed response link to the Next.js frontend at /calendar/serving-response/{connectionUuid}/{assignmentUuid}. The page shows assignment details and records a response only after an explicit form submit. It requires no staff login. The frontend calls the calendar response API from the server; provider tokens and staff credentials are not sent to the page. The API supports GET and POST at /api/calendar/serving-response/{connectionUuid}/{assignmentUuid}. Both require the original query string, in this order: expires=<unix timestamp>&signature=<64 lowercase hexadecimal characters>. The signature covers the relative API path and expiry. Extra or duplicate query parameters are rejected. The signed link authorizes only that assignment in the connection’s church; client and member selectors are not accepted. GET returns success: true and a data object containing title, role, starts_at, ends_at, timezone, location, status, saved, and can_respond. Timestamps are UTC ISO values with the plan’s IANA timezone provided for display; timestamps and location may be null. GET has no response side effects and returns saved: false. POST accepts JSON:
Use confirmed to accept or declined to decline. A decline requires a reason of at most 2,000 characters. A successful POST returns the same data contract with saved: true. A confirmed assignment may be declined later. Declined assignments return can_respond: false; changing one back to confirmed returns HTTP 409. Repeated responses use the existing assignment response service. Invalid or expired signatures return HTTP 403. Revoked connections, mismatched ownership, or assignments no longer available return HTTP 404. Validation errors return HTTP 422; the per-capability rate limit returns HTTP 429. Private responses and redirects use no-store, no-referrer, and noindex headers. Existing absolute signed links on the API host at /calendar/serving-response/{connectionUuid}/{assignmentUuid} remain valid until their original expiry. GET validates the old link and redirects to the frontend with a new relative API signature without extending that expiry. The legacy POST remains CSRF-protected and returns JSON. Laravel no longer renders the member response page. Treat each link as a private bearer capability: anyone who receives it can respond for that assignment. It becomes invalid when its connection is revoked. Keep signed URLs and decline reasons out of logs, analytics, and error reports; application telemetry suppresses these fields, but proxy and access-log query retention must also be configured by the deployment operator.

Deployment

Configure server-only COMPOSIO_API_KEY, COMPOSIO_GOOGLE_CALENDAR_AUTH_CONFIG_ID, and COMPOSIO_OUTLOOK_AUTH_CONFIG_ID. Optional COMPOSIO_BASE_URL defaults to Composio’s API host. Staff OAuth redirects use DASHBOARD_URL; member redirects use the trusted TheFaithApp app link back to the Volunteer Hub. Set FRONTEND_URL to the installation’s HTTPS Next.js origin for serving response links, and APP_URL to the correct API origin for existing absolute signatures. Deploy the frontend page and JSON API together before testing new or legacy calendar response links. For Google, calendar-list read access and event read/write access are required. For Outlook, use calendar read/write and account profile access with refresh authorization. Grant actual provider data access only through the end user’s OAuth consent flow. Providers with missing configuration are unavailable in the dashboard.