Skip to content

API ↔ Frontend Endpoint Map

This document provides a complete picture of every endpoint exposed by apps/api, which pages and components in apps/web and apps/members call each one, and a summary of what is used vs. unused.


Table of Contents

  1. API Endpoints by Controller
  2. apps/web — Pages & API Calls
  3. apps/members — Pages, Components & API Calls
  4. Coverage Table

1. API Endpoints by Controller

Auth note:

  • Admin endpoints (non-member) require a Clerk JWT ******
  • Member portal endpoints (/api/member/*) use a cookie-based session (MemberSessionDefaults), set by POST /api/member/auth/login.
  • POST /api/member/auth/login and GET /api/health are anonymous (no auth required).
  • POST /api/webhooks/clerk is verified by Svix signature — not a ******

AdminController — GET/POST/PUT/DELETE /api/admin

VerbRouteReturn TypeInputs
GET/api/admin/rolesAdminRole[]
POST/api/admin/roles{ adminRoleId }Body: CreateAdminRoleRequest
PUT/api/admin/roles/{id}204 No ContentRoute: id: guid; Body: UpdateAdminRoleRequest
DELETE/api/admin/roles/{id}204 No ContentRoute: id: guid
PUT/api/admin/roles/{id}/permissions204 No ContentRoute: id: guid; Body: SetRolePermissionsRequest
GET/api/admin/permissionsAdminPermission[]
GET/api/admin/usersuser listQuery: search?, isActive?, skip, take
POST/api/admin/login-usersBody: ProvisionLoginUserRequest
GET/api/admin/teamsteam list

ApplicationsController — /api/applications

VerbRouteReturn TypeInputs
GET/api/applicationsPagedResult<MembershipApplicationListItemDto>Query: status?, applicantType?, skip, take
GET/api/applications/{id}MembershipApplicationDetailDtoRoute: id: guid
PUT/api/applications/{id}/approveMembershipApplicationDetailDtoRoute: id: guid; Body: ApproveApplicationRequest
PUT/api/applications/{id}/rejectMembershipApplicationDetailDtoRoute: id: guid; Body: RejectApplicationRequest

AuditController — /api/audit

VerbRouteReturn TypeInputs
GET/api/auditPagedResult<AuditLogDto>Query: entityId?, entityType?, userId?, skip, take
GET/api/audit/{id}AuditLogWithDetailsDtoRoute: id: guid

AuthController — /api/auth

VerbRouteReturn TypeInputs
POST/api/auth/jitJitResponseBody: JitRequest (Clerk JWT required; ClerkId from JWT sub, not body)
GET/api/auth/meJitResponseClerk JWT required

CampaignsController — /api/campaigns

VerbRouteReturn TypeInputs
GET/api/campaigns/summarycampaign summary object
GET/api/campaigns{ total, items }Query: status?, type?, search?, skip, take
GET/api/campaigns/{id}campaign detail objectRoute: id: guid
GET/api/campaigns/{id}/recipients{ total, items }Route: id: guid; Query: skip, take
POST/api/campaigns{ campaignId }Body: CreateCampaignRequest
PUT/api/campaigns/{id}204 No ContentRoute: id: guid; Body: UpdateCampaignRequest
DELETE/api/campaigns/{id}204 No ContentRoute: id: guid

ClerkWebhookController — /api/webhooks/clerk

VerbRouteReturn TypeInputs
POST/api/webhooks/clerk200 OKSvix signature header; raw request body

ContactsController — /api/contacts

VerbRouteReturn TypeInputs
GET/api/contactsPagedResult<ContactListItemDto>Query: skip, take, search?, status?, type?
GET/api/contacts/summarysummary object (counts by status)
GET/api/contacts/export501 Not Implemented
GET/api/contacts/{id}ContactDetailDtoRoute: id: guid
POST/api/contactsContactListItemDtoBody: CreateContactRequest
PUT/api/contacts/{id}ContactDetailDtoRoute: id: guid; Body: UpdateContactRequest
DELETE/api/contacts/{id}204 No ContentRoute: id: guid

DashboardController — /api/dashboard

VerbRouteReturn TypeInputs
GET/api/dashboard/statsDashboardStatsDto
GET/api/dashboard/growthGrowthPointDto[]
GET/api/dashboard/renewals-dueDashboardRenewalsDueDtoQuery: take
GET/api/dashboard/activityActivityItemDto[]Query: take

EventsController — /api/events

VerbRouteReturn TypeInputs
GET/api/events/summaryEventSummaryDto
GET/api/eventsPagedResult<EventListItemDto>Query: search?, statusFilter?, skip, take
GET/api/events/{id}EventDetailDtoRoute: id: guid
POST/api/events{ eventId }Body: CreateEventRequest
PUT/api/events/{id}204 No ContentRoute: id: guid; Body: UpdateEventRequest
DELETE/api/events/{id}204 No ContentRoute: id: guid
GET/api/events/{id}/registrationsPagedResult<EventRegistrationListItemDto>Route: id: guid; Query: skip, take
GET/api/events/{id}/sessionsEventSessionListItemDto[]Route: id: guid
POST/api/events/{id}/cancel204 No ContentRoute: id: guid

HealthController — /api/health

VerbRouteReturn TypeInputs
GET/api/health{ Status: "Healthy" }— (anonymous, no auth required)

InvoicesController — /api/invoices

VerbRouteReturn TypeInputs
GET/api/invoices/summaryInvoiceSummaryDto
GET/api/invoicesPagedResult<InvoiceListItemDto>Query: partyId?, statusFilter?, search?, skip, take
GET/api/invoices/{id}/paymentspayment listRoute: id: guid
GET/api/invoices/{id}InvoiceDetailDtoRoute: id: guid
POST/api/invoices/{id}/void204 No ContentRoute: id: guid
POST/api/invoices{ invoiceId }Body: CreateInvoiceRequest
PUT/api/invoices/{id}InvoiceDetailDtoRoute: id: guid; Body: UpdateInvoiceRequest

MediaController — /api/member/media

VerbRouteReturn TypeInputs
GET/api/member/media/{*storageKey}file content (binary)Route: storageKey (wildcard); Member session auth

MemberAuthController — /api/member/auth

VerbRouteReturn TypeInputs
POST/api/member/auth/loginMemberAuthUserDto + session cookieBody: MemberLoginRequest { email, password } (anonymous)
POST/api/member/auth/logout204 No ContentMember session auth
GET/api/member/auth/mesession user infoMember session auth

MemberCertificatesController — /api/member/certificates

VerbRouteReturn TypeInputs
GET/api/member/certificatesMemberCertificateDto[]Member session auth

MemberCertificationsController — /api/member/certifications

VerbRouteReturn TypeInputs
POST/api/member/certificationsMemberCertificationDtoMultipart form: file, title, issuingAuthority?; Member session auth

MemberCommunicationsController — /api/member/communications

VerbRouteReturn TypeInputs
GET/api/member/communications/preferencesMemberCommunicationPreferenceDto[]Member session auth
PUT/api/member/communications/preferencesMemberCommunicationPreferenceDto[]Body: MemberCommunicationPreferenceUpdateRequest[]; Member session auth

MemberEventsController — /api/member/events

VerbRouteReturn TypeInputs
GET/api/member/events/upcomingMemberUpcomingEventDto[]Member session auth

MemberInvoicesController — /api/member/invoices

VerbRouteReturn TypeInputs
GET/api/member/invoicesMemberInvoiceListDtoQuery: limit; Member session auth

MemberMembershipController — /api/member/membership

VerbRouteReturn TypeInputs
GET/api/member/membership/currentMemberCurrentMembershipDtoMember session auth
POST/api/member/membership/renewMemberRenewResponseBody: MemberRenewRequest; Member session auth

MemberProfileController — /api/member/profile

VerbRouteReturn TypeInputs
GET/api/member/profileMemberSelfProfileDtoMember session auth
GET/api/member/profile/completenessMemberCompletenessDtoMember session auth
PATCH/api/member/profileMemberSelfProfileDtoBody: MemberProfileUpdateRequest; Member session auth

MembersController — /api/members

VerbRouteReturn TypeInputs
GET/api/membersPagedResult<MemberListItemDto>Query: search?, status?, skip, take
GET/api/members/summarysummary object
GET/api/members/export501 Not Implemented
GET/api/members/{id}MemberDetailDtoRoute: id: guid
POST/api/membersMemberListItemDtoBody: CreateMemberRequest
PUT/api/members/{id}MemberDetailDtoRoute: id: guid; Body: UpdateMemberRequest
DELETE/api/members/{id}204 No ContentRoute: id: guid

MembershipPlansController — /api/membership-plans

VerbRouteReturn TypeInputs
GET/api/membership-plansMembershipPlanListItemDto[]Query: isActive?

MembershipsController — /api/memberships

VerbRouteReturn TypeInputs
GET/api/membershipsPagedResult<MembershipListItemDto>Query: status?, planId?, expiryWindow?, autoRenew?, skip, take
GET/api/memberships/duePagedResult<MembershipListItemDto>Query: days, autoRenew?, skip, take
POST/api/memberships/batch-renewRenewalBatchResultBody: RenewalBatchRequest { membershipIds[] }
POST/api/memberships/{id}/renew204 No ContentRoute: id: guid
GET/api/memberships/{id}membership detailRoute: id: guid
POST/api/memberships204 No ContentBody: CreateMembershipRequest
PUT/api/memberships/{id}204 No ContentRoute: id: guid; Body: UpdateMembershipRequest
DELETE/api/memberships/{id}204 No ContentRoute: id: guid

PaymentsController — /api/payments

VerbRouteReturn TypeInputs
GET/api/paymentsPagedResult<PaymentListItemDto>Query: partyId?, search?, skip, take
GET/api/payments/{id}PaymentDetailDtoRoute: id: guid
POST/api/paymentsPaymentDetailDtoBody: RecordPaymentRequest

PeopleController — /api/people

VerbRouteReturn TypeInputs
GET/api/peopleParty[]Query: skip, take

ReportsController — /api/reports

VerbRouteReturn TypeInputs
GET/api/reportsReportDefinitionDto[]Query: reportType?, isActive?
GET/api/reports/recent-runsReportRunDto[]Query: take
GET/api/reports/runs/{runId}ReportRunDtoRoute: runId: guid
POST/api/reports/{id}/runReportRunDtoRoute: id: guid

2. apps/web — Pages & API Calls

Authentication model: apps/web uses Clerk JWT. On each sign-in the auth store calls POST /api/auth/jit once to provision/resolve the user and obtain role + permissions. GET /api/auth/me is called on-demand to refresh permissions without a new sign-in. All other API calls use the useApi() composable or direct ofetch() calls with the Clerk ******

Redirect-only pages (no API calls): pages/members/index.vue/contacts/, pages/members/[id].vue/contacts/[id], pages/marketing/*/communications/*, pages/prospects.vue/memberships/applications.


pages/index.vue — Dashboard home

VerbEndpointController
GET/api/dashboard/statsDashboardController
GET/api/dashboard/growthDashboardController
GET/api/dashboard/renewals-dueDashboardController
GET/api/dashboard/activityDashboardController

pages/contacts/index.vue — Contacts list

VerbEndpointController
GET/api/contactsContactsController
GET/api/contacts/summaryContactsController
POST/api/contactsContactsController

pages/contacts/[id].vue — Contact detail

VerbEndpointController
GET/api/contacts/{id}ContactsController
PUT/api/contacts/{id}ContactsController
GET/api/invoices?partyId={id}InvoicesController
GET/api/audit?entityId={id}&entityType=PartyAuditController
GET/api/membership-plansMembershipPlansController
POST/api/memberships/{id}/renewMembershipsController
POST/api/membershipsMembershipsController

pages/events/index.vue — Events list

VerbEndpointController
GET/api/events/summaryEventsController
GET/api/eventsEventsController
POST/api/eventsEventsController

pages/events/[id].vue — Event detail

VerbEndpointController
GET/api/events/{id}EventsController
GET/api/events/{id}/registrationsEventsController
GET/api/events/{id}/sessionsEventsController
POST/api/events/{id}/cancelEventsController
PUT/api/events/{id}EventsController

pages/communications/index.vue — Campaigns list

VerbEndpointController
GET/api/campaigns/summaryCampaignsController
GET/api/campaignsCampaignsController
POST/api/campaignsCampaignsController

pages/communications/[id].vue — Campaign detail

VerbEndpointController
GET/api/campaigns/{id}CampaignsController
GET/api/campaigns/{id}/recipientsCampaignsController
PUT/api/campaigns/{id}CampaignsController
DELETE/api/campaigns/{id}CampaignsController

pages/communications/editor.vue — Campaign editor

VerbEndpointController
GET/api/campaigns/{id}CampaignsController
PUT/api/campaigns/{id}CampaignsController

pages/payments/index.vue — Payments / invoices list

VerbEndpointController
GET/api/invoices/summaryInvoicesController
GET/api/invoicesInvoicesController

pages/payments/[invoice].vue — Invoice detail

VerbEndpointController
GET/api/invoices/{id}InvoicesController
GET/api/invoices/{id}/paymentsInvoicesController
POST/api/invoices/{id}/voidInvoicesController

pages/memberships/index.vue — Memberships list

VerbEndpointController
GET/api/membershipsMembershipsController

pages/memberships/applications.vue — Applications

VerbEndpointController
GET/api/applicationsApplicationsController
GET/api/applications/{id}ApplicationsController
PUT/api/applications/{id}/approveApplicationsController
PUT/api/applications/{id}/rejectApplicationsController

pages/memberships/renewals.vue & pages/renewals/batch.vue — Batch renewals

Both pages contain identical logic; renewals/batch.vue appears to be a legacy duplicate.

VerbEndpointController
GET/api/memberships/dueMembershipsController
POST/api/memberships/batch-renewMembershipsController

pages/settings/roles.vue — Role management

VerbEndpointController
GET/api/admin/rolesAdminController
GET/api/admin/permissionsAdminController
PUT/api/admin/roles/{id}AdminController
POST/api/admin/rolesAdminController
PUT/api/admin/roles/{id}/permissionsAdminController

pages/settings/audit.vue — Audit log

VerbEndpointController
GET/api/auditAuditController

pages/reports/index.vue — Recent report runs

VerbEndpointController
GET/api/reports/recent-runsReportsController

pages/reports/library.vue — Report library

VerbEndpointController
GET/api/reportsReportsController
POST/api/reports/{id}/runReportsController

pages/login.vue, pages/about.vue, pages/resources/index.vue, pages/[...404].vue

No API calls. (resources/index.vue shows a static "coming soon" placeholder.)


Auth Store — stores/auth.ts

Called globally (not from a single page), triggered by Clerk sign-in state:

VerbEndpointControllerWhen
POST/api/auth/jitAuthControllerOnce per session on sign-in
GET/api/auth/meAuthControllerOn-demand permission refresh

3. apps/members — Pages, Components & API Calls

Authentication model: apps/members uses a cookie-based session. POST /api/member/auth/login sets the session; all other member endpoints require the session cookie. All API calls are routed through the useMemberApi() composable (in app/composables/useMemberApi.ts), which wraps useApi()apiFetch().


pages/login.vue — Member login

VerbEndpointController
POST/api/member/auth/loginMemberAuthController

pages/index.vue — Public landing page

No API calls. Marketing/landing page visible before login.


pages/account/index.vue — Member dashboard

All calls made on mount via useMemberApi():

VerbEndpointController
GET/api/member/profileMemberProfileController
GET/api/member/profile/completenessMemberProfileController
GET/api/member/membership/currentMemberMembershipController
GET/api/member/invoicesMemberInvoicesController
GET/api/member/certificatesMemberCertificatesController
GET/api/member/events/upcomingMemberEventsController
GET/api/member/communications/preferencesMemberCommunicationsController

pages/account/events.vue — Events sub-page

No API calls. Static placeholder linking back to dashboard.


pages/account/invoices.vue — Invoices sub-page

No API calls. Static placeholder linking back to dashboard.


components/members/MembersBand.vue — Nav/header band

VerbEndpointController
POST/api/member/auth/logoutMemberAuthController

components/members/renew/RenewNowModal.vue — Renew membership modal

VerbEndpointController
POST/api/member/membership/renewMemberMembershipController

components/members/edit/EditProfileModal.vue — Edit personal profile

VerbEndpointController
PATCH/api/member/profileMemberProfileController

components/members/edit/EditBusinessDetailsModal.vue — Edit organisation profile

VerbEndpointController
PATCH/api/member/profileMemberProfileController

components/members/edit/FinishProfileModal.vue — Complete profile wizard

VerbEndpointController
PATCH/api/member/profileMemberProfileController

components/members/edit/EditCommunicationsModal.vue — Edit communication preferences

VerbEndpointController
PUT/api/member/communications/preferencesMemberCommunicationsController

components/members/upload/UploadCertificateModal.vue — Upload certification

VerbEndpointController
POST/api/member/certificationsMemberCertificationsController

Display-only components (no API calls)

These receive data via props from the dashboard page and make no direct API calls:

MembershipCard, InvoicesCard, CertificationsCard, UpcomingEventsCard, CommunicationsCard, PersonalDetailsCard, BusinessDetailsCard, ProfileCompletenessCard, MembersHero, MembersNav, MembersFooter, QuickActions, CardError, Toaster


4. Coverage Table

The table below shows every API endpoint and which frontend project(s) consume it.

Endpointapps/webapps/membersStatus
AdminController
GET /api/admin/rolessettings/roles.vue✅ Used
POST /api/admin/rolessettings/roles.vue✅ Used
PUT /api/admin/roles/{id}settings/roles.vue✅ Used
DELETE /api/admin/roles/{id}⚠️ Unused
PUT /api/admin/roles/{id}/permissionssettings/roles.vue✅ Used
GET /api/admin/permissionssettings/roles.vue✅ Used
GET /api/admin/users⚠️ Unused
POST /api/admin/login-users⚠️ Unused
GET /api/admin/teams⚠️ Unused
ApplicationsController
GET /api/applicationsmemberships/applications.vue✅ Used
GET /api/applications/{id}memberships/applications.vue✅ Used
PUT /api/applications/{id}/approvememberships/applications.vue✅ Used
PUT /api/applications/{id}/rejectmemberships/applications.vue✅ Used
AuditController
GET /api/auditsettings/audit.vue, contacts/[id].vue✅ Used
GET /api/audit/{id}⚠️ Unused
AuthController
POST /api/auth/jitstores/auth.ts✅ Used
GET /api/auth/mestores/auth.ts✅ Used
CampaignsController
GET /api/campaigns/summarycommunications/index.vue✅ Used
GET /api/campaignscommunications/index.vue✅ Used
GET /api/campaigns/{id}communications/[id].vue, editor.vue✅ Used
GET /api/campaigns/{id}/recipientscommunications/[id].vue✅ Used
POST /api/campaignscommunications/index.vue✅ Used
PUT /api/campaigns/{id}communications/[id].vue, editor.vue✅ Used
DELETE /api/campaigns/{id}communications/[id].vue✅ Used
ClerkWebhookController
POST /api/webhooks/clerk— (Clerk infrastructure)✅ Used (external)
ContactsController
GET /api/contactscontacts/index.vue✅ Used
GET /api/contacts/summarycontacts/index.vue✅ Used
GET /api/contacts/export⚠️ Unused (501)
GET /api/contacts/{id}contacts/[id].vue✅ Used
POST /api/contactscontacts/index.vue✅ Used
PUT /api/contacts/{id}contacts/[id].vue✅ Used
DELETE /api/contacts/{id}⚠️ Unused
DashboardController
GET /api/dashboard/statspages/index.vue✅ Used
GET /api/dashboard/growthpages/index.vue✅ Used
GET /api/dashboard/renewals-duepages/index.vue✅ Used
GET /api/dashboard/activitypages/index.vue✅ Used
EventsController
GET /api/events/summaryevents/index.vue✅ Used
GET /api/eventsevents/index.vue✅ Used
GET /api/events/{id}events/[id].vue✅ Used
POST /api/eventsevents/index.vue✅ Used
PUT /api/events/{id}events/[id].vue✅ Used
DELETE /api/events/{id}⚠️ Unused
GET /api/events/{id}/registrationsevents/[id].vue✅ Used
GET /api/events/{id}/sessionsevents/[id].vue✅ Used
POST /api/events/{id}/cancelevents/[id].vue✅ Used
HealthController
GET /api/health— (infra/monitoring)✅ Used (external)
InvoicesController
GET /api/invoices/summarypayments/index.vue✅ Used
GET /api/invoicespayments/index.vue, contacts/[id].vue✅ Used
GET /api/invoices/{id}/paymentspayments/[invoice].vue✅ Used
GET /api/invoices/{id}payments/[invoice].vue✅ Used
POST /api/invoices/{id}/voidpayments/[invoice].vue✅ Used
POST /api/invoices⚠️ Unused
PUT /api/invoices/{id}⚠️ Unused
MediaController
GET /api/member/media/{*storageKey}⚠️ Unused (no frontend call found)
MemberAuthController
POST /api/member/auth/loginpages/login.vue✅ Used
POST /api/member/auth/logoutMembersBand.vue✅ Used
GET /api/member/auth/me⚠️ Unused (no frontend call found)
MemberCertificatesController
GET /api/member/certificatespages/account/index.vue✅ Used
MemberCertificationsController
POST /api/member/certificationsUploadCertificateModal.vue✅ Used
MemberCommunicationsController
GET /api/member/communications/preferencespages/account/index.vue✅ Used
PUT /api/member/communications/preferencesEditCommunicationsModal.vue✅ Used
MemberEventsController
GET /api/member/events/upcomingpages/account/index.vue✅ Used
MemberInvoicesController
GET /api/member/invoicespages/account/index.vue✅ Used
MemberMembershipController
GET /api/member/membership/currentpages/account/index.vue✅ Used
POST /api/member/membership/renewRenewNowModal.vue✅ Used
MemberProfileController
GET /api/member/profilepages/account/index.vue✅ Used
GET /api/member/profile/completenesspages/account/index.vue✅ Used
PATCH /api/member/profileEditProfileModal.vue, EditBusinessDetailsModal.vue, FinishProfileModal.vue✅ Used
MembersController
GET /api/members⚠️ Unused (web uses /api/contacts instead)
GET /api/members/summary⚠️ Unused
GET /api/members/export⚠️ Unused (501)
GET /api/members/{id}⚠️ Unused
POST /api/members⚠️ Unused
PUT /api/members/{id}⚠️ Unused
DELETE /api/members/{id}⚠️ Unused
MembershipPlansController
GET /api/membership-planscontacts/[id].vue✅ Used
MembershipsController
GET /api/membershipsmemberships/index.vue✅ Used
GET /api/memberships/duememberships/renewals.vue, renewals/batch.vue✅ Used
POST /api/memberships/batch-renewmemberships/renewals.vue, renewals/batch.vue✅ Used
POST /api/memberships/{id}/renewcontacts/[id].vue✅ Used
GET /api/memberships/{id}⚠️ Unused
POST /api/membershipscontacts/[id].vue✅ Used
PUT /api/memberships/{id}⚠️ Unused
DELETE /api/memberships/{id}⚠️ Unused
PaymentsController
GET /api/payments⚠️ Unused
GET /api/payments/{id}⚠️ Unused
POST /api/payments⚠️ Unused
PeopleController
GET /api/people⚠️ Unused
ReportsController
GET /api/reportsreports/library.vue✅ Used
GET /api/reports/recent-runsreports/index.vue✅ Used
GET /api/reports/runs/{runId}⚠️ Unused
POST /api/reports/{id}/runreports/library.vue✅ Used

Summary

CategoryCount
Total API endpoints74
✅ Used by apps/web46
✅ Used by apps/members14
✅ Used by both0 (separate auth schemes)
✅ Used externally (health/webhooks)2
⚠️ Unused by any frontend22

Unused endpoints to investigate

The following endpoints have no frontend consumer and may be candidates for removal, future feature scaffolding, or need a UI built:

  • AdminController: DELETE /api/admin/roles/{id}, GET /api/admin/users, POST /api/admin/login-users, GET /api/admin/teams
  • AuditController: GET /api/audit/{id}
  • ContactsController: GET /api/contacts/export (501), DELETE /api/contacts/{id}
  • EventsController: DELETE /api/events/{id}
  • InvoicesController: POST /api/invoices (create), PUT /api/invoices/{id} (update)
  • MediaController: GET /api/member/media/{*storageKey}
  • MemberAuthController: GET /api/member/auth/me
  • MembersController: all 7 endpoints (the web app redirects /members/* to /contacts/* and uses ContactsController exclusively — MembersController appears to be a superseded parallel implementation)
  • MembershipsController: GET /api/memberships/{id}, PUT /api/memberships/{id}, DELETE /api/memberships/{id}
  • PaymentsController: all 3 endpoints (GET /api/payments, GET /api/payments/{id}, POST /api/payments)
  • PeopleController: GET /api/people
  • ReportsController: GET /api/reports/runs/{runId}