Awn Awn
Back to Awn
Documentation menu — Routes and middleware
Reference / Routes and middleware
Version
1.0
Last verified
2026-08-09

Routes and middleware reference

Developer handbook pages use GET /developers/docs/{page?} (developers.docs) with registered nested paths such as build/plugins.

Donor identity

  • GET|POST /donor/register → donor.register, donor.register.store; registration POST is throttled.
  • GET|POST /donor/login → donor.login, donor.login.store; guest-only and throttled.
  • GET /donor/verify-phone → donor.verification.notice; auth, donor.
  • POST /donor/verify-phone/send → donor.verification.send; auth, donor, throttled.
  • POST /donor/verify-phone → donor.verification.verify; auth, donor, throttled.
  • GET /donor/dashboard → donor.dashboard; auth, donor, phone.verified.
  • POST /donor/logout → donor.logout; auth, donor.

The central /login and /register remain email-based staff/organization flows.

Site

  • GET /preview/{organizationSlug}/{path?} → site.preview; signed, organization.route.
  • GET /s/{organizationSlug}/{path?} → site.path; organization.route; local mode.
  • GET {organizationSlug}.{central_domain}/{path?} → site.subdomain; organization.route; domain mode.

Charity

Prefix /charity/{organization:slug}, names charity.*, middleware auth, organization.route, organization.member:

  • GET / → charity.dashboard; GET /preview → charity.site.preview.
  • GET|PUT /appearance → charity.themes.index, charity.themes.update.
  • GET /plugins → charity.plugins.index.
  • GET|PUT /plugins/{plugin} → charity.plugins.show, charity.plugins.update.
  • PATCH /plugins/{plugin}/status → charity.plugins.toggle.

Admin

auth, super.admin: GET /admin (admin.dashboard), GET /admin/organizations (admin.organizations.index), GET /admin/plugins (admin.plugins.index), POST /admin/organizations/{organization}/impersonate (admin.organizations.impersonate). POST /admin/impersonation/stop (admin.impersonation.stop) uses auth.

Plugin Super Admin routes use /admin/plugins/{slug}/manage, plugin.{slug}.admin.*, and web, auth, super.admin, plugin.available:{slug},installed. They must not use organization middleware.

Contact Form

  • GET /charity/{organization:slug}/plugins/contact-form/manage → plugin.contact-form.dashboard; web, auth, route tenant, member, plugin.available:contact-form,installed.
  • POST /s/{organizationSlug}/_plugins/contact-form → plugin.contact-form.site.path.store; web, route tenant, enabled availability, throttle:5,1.
  • Equivalent domain POST → plugin.contact-form.site.subdomain.store; same guards.

Events

Prefix /charity/{organization:slug}/plugins/events/manage, plugin.events.dashboard.*, web, auth, route tenant, member, plugin.available:events,installed:

  • GET / → plugin.events.dashboard.index;
  • GET /create → plugin.events.dashboard.create;
  • POST / → plugin.events.dashboard.store;
  • GET /{event}/edit → plugin.events.dashboard.edit;
  • PUT /{event} → plugin.events.dashboard.update;
  • DELETE /{event} → plugin.events.dashboard.destroy.

Public Events GET pages use the site catch-all, not plugin routes. Karam Banner has no endpoints.

Fundraising

Settings remain on the Charity routes at /charity/{organization:slug}/plugins/fundraising. Management uses the separate prefix /charity/{organization:slug}/plugins/fundraising/manage to prevent settings/dashboard collisions. Every management route uses web, auth, organization.route, organization.member, and plugin.available:fundraising.

  • GET / → plugin.fundraising.dashboard.overview.
  • GET /projects → plugin.fundraising.dashboard.projects.index.
  • GET /projects/create and POST /projects → plugin.fundraising.dashboard.projects.create, plugin.fundraising.dashboard.projects.store.
  • GET /projects/{project} → plugin.fundraising.dashboard.projects.show.
  • GET /projects/{project}/edit and PUT /projects/{project} → plugin.fundraising.dashboard.projects.edit, plugin.fundraising.dashboard.projects.update.
  • PATCH /projects/{project}/status → plugin.fundraising.dashboard.projects.status.
  • DELETE /projects/{project} → plugin.fundraising.dashboard.projects.destroy.
  • GET /donations and GET /donations/review → plugin.fundraising.dashboard.donations.index, plugin.fundraising.dashboard.donations.review.
  • GET /donations/{donation} → plugin.fundraising.dashboard.donations.show.
  • PATCH /donations/{donation}/status → plugin.fundraising.dashboard.donations.status.
  • GET /donations/{donation}/proof → plugin.fundraising.dashboard.donations.proof; policy-protected private download.
  • GET /channels, GET /channels/create, POST /channels → plugin.fundraising.dashboard.channels.index, plugin.fundraising.dashboard.channels.create, plugin.fundraising.dashboard.channels.store.
  • GET /channels/{channel}/edit, PUT /channels/{channel} → plugin.fundraising.dashboard.channels.edit, plugin.fundraising.dashboard.channels.update.
  • PATCH /channels/{channel}/status, DELETE /channels/{channel} → plugin.fundraising.dashboard.channels.toggle, plugin.fundraising.dashboard.channels.destroy.
  • GET /supporters → plugin.fundraising.dashboard.supporters.index.
  • GET /reports → plugin.fundraising.dashboard.reports.index.

Public project GET pages resolve through the site catch-all at projects and projects/{project}. Manual submission uses POST /donate/{organizationSlug}/projects/{project} → plugin.fundraising.donate with web, organization.route, enabled availability, and throttle:20,1.

Fundraising also contributes read-only Super Admin routes:

  • GET /admin/plugins/fundraising/manage → plugin.fundraising.admin.overview.
  • GET /admin/plugins/fundraising/manage/projects → plugin.fundraising.admin.projects.index.
  • GET /admin/plugins/fundraising/manage/donations → plugin.fundraising.admin.donations.index.

All three use web, auth, super.admin, and plugin.available:fundraising,installed.

EnsurePluginAvailable::handle(Request $request, Closure $next, string $plugin, string $mode = 'enabled'): Response always checks installed/active; enabled mode also checks effective tenant state.