Skip to content
Generated from server/trpc and server/api

API

252 tRPC procedures in 39 routers and 27 REST / webhook handlers, read from the live router and the handler files on every build.

How auth works

public

Anyone. Built on publicProcedure.

protected

Signed-in dancer (Bearer session token). protectedProcedure.

admin

adminProcedure. 18 exist; they are listed only on the admin catalog.

Auth level is read from the procedure's middleware at build time, not from naming.

Routers

auth10
dinner3
festivalSignup8

not a valid UUID

claim2

Magic-link claim flow for TicketTailor verified attendees.

festival2

Public festival read APIs.

festivalInsights2

Organizer insights for a festival (the "dashboard" promised on /organizers).

cityVideo8

Current competition month key, e.g. '2026-07' (UTC).

giveaway5

A proposal with what the organizer needs to decide.

profile3

Public dancer profiles + self-service editing.

review2

One review per dancer per target. Denormalizes the reviewer's name + handle onto the row so the list needs no join. Shared by review.create (a normal star review) and askLocals.recommend (an auto-5★ recommendation) — `source` distinguishes them. Manual select-then-insert/update (not onConflictDoUpdate) so it works against the hermetic FakeDb in tests too; the unique constraint is the real backstop.

communityGroup2

Community groups directory — the cold-start filler for cities where WeDance has no events yet. Public read per city; admin/bulk create (the Commander's existing list is imported via the seed / an admin import).

askLocals3

"Ask locals" — a newcomer posts a question for a city; locals answer by recommending an organizer or venue. A recommendation writes into the reviews spine as an auto-5★ review (source='recommendation'), auto-stubbing the target by slug so repeated recommendations of the same place aggregate.

entity8

Professional profiles (venue / artist / organizer) resolved by handle for the unified /@<handle> route. Returns the profile + its bookable spaces (venues). Dancers are resolved separately (profile.getByUsername); the /@handle page tries this first, then the dancer.

booking6

Booking requests — connector model (WeDance holds no money). An organizer requests a date for a bookable space; the venue responds off-platform for now. Public so organizers can request without an account (email required); the caller's dancerId is captured when signed in. Terms must be accepted.

election10

Moderator elections — community governance for free/OpenAir commons (epic G800, WED-152). A space's moderator is elected annually; candidates propose the guidelines the space runs by (G802); the community votes on an OPEN, verifiable ledger — timestamped, attributable, editable-with-history (G803); the winner's guidelines become the active ruleset the moderator enforces on the free-booking queue (G804). Eligibility: real (verified) profile, one vote per profile (G801).

feedback2

Feedback router.

gigs8

Gigs this dancer answers for: posted by them, or by a page they run (and the app may use).

hangouts8

A city slug as stored on events/hangouts, from a slug or a typed city name ("München" → "munich").

events7

Public dated events from the `events` table — today the live mirror of wedance.vip (v3) events written by scripts/sync-v3-events.ts. Only rows that are published and not archived are listed; the 9,580 historical v4 imports stay archived/unpublished and never surface here.

plan20

Batch count of plan items per event/festival. Returns a map of itemId → count. Used by city pages to populate attendee counts on event cards without N+1 queries.

referral8

Referrals (dancer → dancer festival tickets with a discount) and, since MCP phase 2, promoter tracked links: one link per promoter page + event (server/utils/trackedLinks.ts), what each link brought, the promoter dashboard and the promo kit.

rideShare3
follow7

Toggle follow on a profile (artist/organizer/venue). Idempotent: if already following, unfollows; if not, follows. Returns the new state: { following: boolean }.

business10

Business mode — artists, venues and organizers managing their own profile.

businessEvents18

Business mode — events a profile runs, and the /business home inbox.

businessFlyers15

server_flyer_generated — every paint request (each is an AI image call). `mode`: paint (new, in a look) / direction (fresh ideas) / again / recompose (4:5 feed post) / fix / refresh. Keeping one is `server_flyer_kept`.

artistInvites9

Artist confirmation. An organizer's photo, video or name for an artist in their line-up is a pending suggestion on the artist's profile (the event uses it right away). The organizer copies a personal link for each artist; the artist opens it, approves or changes what's there, adds more — and, when nobody owns the page yet, creates an account and owns it.

venueAsks4

Asking venues through WeDance — the venue twin of the artist link. The organizer asks one or more venues for an event (what they need, how many guests); each venue gets a personal link (/confirm/<token>, the same page as artists) and answers: can host it, another date, or no — with its terms. The organizer compares the answers and books one; the others' links then say it was booked elsewhere. A venue whose page someone runs here also gets the ask under "Needs you" on its Business home (no notification is sent).

inquiries5

Booking inquiries — anyone asks to book an artist or venue from their page (/@handle, or /@handle/book on the artist's own site), no account needed. The page's team is emailed (Reply-To = the asker) and sees it under "Needs you"; nobody running it → its private booking email, else WeDance passes it on. Limits: 3 a day per asker per page, 10 a day per asker, 30 a day per page.

businessPosts8

Business mode — an event's content plan (event_posts): the posts it's promoted with, each made with the flyer pipeline in the event's look (/business/events/<id>/flyer?post=<post>). Proposing a plan only lists the posts; nothing paints until the organizer clicks.

businessLooks6

Business mode — a profile's flyer styles (brand_looks): the looks its flyers are painted in. "Yours" are read off its own flyers or kept from a painting; "ideas" (source 'generated') are suggestions Gemini wrote for it, painted only when picked. The description is the prompt the look is painted from, editable as text.

businessSite5

A profile's website and contacts, managed on WeDance (RAZ-412): /business/network/<username>/website edits the page (sections, words in every language, the welcome email), /business/network/<username>/contacts lists who signed up on it. The site reads /api/profiles/<username>/site.

businessTeam6

Business mode — teams. Who may join a profile, with which role, and who decides:

businessNetwork4

Business mode — Network (RAZ-408). The artists, venues and organizers a page works with.

roommate2
wave7

A swipe card is a photo: dancers without one never enter the deck.

organizerSubscription2

Returns the active Network subscription for a profile, or null. Public so the organizers page can show the plan status without auth.

attendance8

Set attendance status for an event. 'none' removes the attendance. Default visibility = hidden (opt-in, per RAZ-313).

oauth6

The dancer's side of connected apps (MCP): the /oauth/authorize consent screen and /settings/connections. Web sessions only: none of these paths is in server/trpc/scopes.ts, so an app's token can never call them (an app can't approve its own consent or list other connections).

All procedures

127 queries · 125 mutations · 76 public · 176 signed-in

252 shown
ProcedureKindAuthTables
auth.requestMagicLinkmutationpublicdancers, tracked_link_actions, tracked_links
auth.verifyMagicLinkmutationpublicdancers, sessions
auth.resetPasswordmutationpublicdancers, sessions
auth.loginmutationpublicdancers, sessions
auth.registermutationpublicbooking_inquiries, dancers, sessions, tracked_link_actions, tracked_links
auth.changePasswordmutationprotecteddancers
auth.completeOnboardingmutationprotecteddancers
auth.mequerypublicdancers
auth.myEmailqueryprotecteddancers
auth.deleteAccountmutationprotectedbooking_requests, city_battle_votes, city_videos, community_group_reports, dancers, dinner_group_members, dinner_signups, election_candidates, election_vote_history, election_votes, festival_ride_shares, festival_roommate_lookups, festival_signups, festival_submissions, gigs, giveaway_entries, guideline_versions, hangout_rsvps, hangouts, moderator_elections, plan_items, profiles, recommendation_requests, referrals, reviews, sessions, video_votes
dinner.listquerypublicdancers, dinner_group_members, dinner_groups, dinner_signups, dinners, festivals
dinner.joinmutationprotecteddinner_signups, dinners
dinner.leavemutationprotecteddinner_group_members, dinner_groups, dinner_signups
festivalSignup.statusquerypublicfestival_signups, festivals
festivalSignup.joinmutationprotectedevents, festival_signups, festivals, tracked_link_actions, tracked_links
festivalSignup.createCheckoutSessionmutationprotectedfestival_signups, festivals
festivalSignup.ticketCheckoutmutationprotecteddancers, festival_signups, festivals, referrals
festivalSignup.publicRosterquerypublicdancers, festival_signups, festivals
festivalSignup.setMyVisibilitymutationprotectedfestival_signups, festivals
festivalSignup.getMyVisibilityqueryprotectedfestival_signups, festivals
festivalSignup.myTicketsqueryprotectedfestival_signups, festivals
claim.claimMyTicketHolderRowsmutationprotecteddancers, festival_signups, festivals
claim.getClaimStatusqueryprotecteddancers, festival_signups, festivals
festival.bySlugquerypublicfestivals
festival.submitDraftmutationpublicfestival_submissions
festivalInsights.myFestivalsqueryprotectedfestival_submissions, festivals
festivalInsights.styleLevelMixqueryprotecteddancers, festival_signups, festival_submissions, festivals
cityVideo.listApprovedquerypubliccity_videos
cityVideo.monthWinnerquerypubliccity_videos
cityVideo.getPairquerypubliccity_videos, video_votes
cityVideo.votemutationpubliccity_videos, video_votes
cityVideo.submitmutationpubliccity_videos
cityVideo.battleMatchupquerypubliccity_battle_votes, city_videos, profiles
cityVideo.battleVotemutationpubliccity_battle_votes
cityVideo.cityLeaderboardquerypubliccity_battle_votes, profiles
giveaway.listActivequerypublicgiveaways
giveaway.entermutationpublicgiveaway_entries, giveaways
giveaway.proposemutationprotectedevents, giveaway_proposals, profile_members, profiles
giveaway.proposalsqueryprotectedevents, giveaway_proposals, profile_members, profiles
giveaway.decideProposalmutationprotectedevents, giveaway_proposals, giveaways, profile_members, profiles, tracked_links
profile.movedToquerypublicdancers
profile.getByUsernamequerypubliccity_videos, dancers
profile.updatemutationprotecteddancers
review.listquerypublicreviews
review.createmutationprotecteddancers, reviews
communityGroup.listByCityquerypubliccommunity_groups
communityGroup.reportmutationprotectedcommunity_group_reports, community_groups
askLocals.listByCityquerypublicrecommendation_requests
askLocals.askmutationprotectedrecommendation_requests
askLocals.recommendmutationprotecteddancers, reviews
entity.listVenuesquerypublicprofiles
entity.listArtistsquerypublicprofiles
entity.listCitiesquerypublicprofiles
entity.cityDirectoryquerypublicprofiles
entity.listByCityquerypublicprofiles
entity.movedToquerypublicprofiles
entity.getByHandlequerypublicbookable_spaces, profiles
entity.promoterRosterquerypublicnetwork_links, profiles
booking.scheduleForProfilequerypublicbooking_requests
booking.upcomingByCityquerypublicbooking_requests, profiles
booking.getEventquerypublicbookable_spaces, booking_requests, profiles
booking.requestmutationpublicavailability_slots, bookable_spaces, booking_requests, profiles
booking.availabilityForProfilequerypublicavailability_slots, bookable_spaces
booking.setAvailabilitymutationprotectedavailability_slots, bookable_spaces, profile_members
election.forProfilequerypublicdancers, election_candidates, election_votes, moderator_elections
election.myVotequeryprotectedelection_vote_history, election_votes
election.openmutationprotectedmoderator_elections, profile_members
election.nominatemutationprotecteddancers, election_candidates, moderator_elections
election.advanceToVotingmutationprotectedelection_candidates, moderator_elections, profile_members
election.castVotemutationprotecteddancers, election_candidates, election_vote_history, election_votes, moderator_elections
election.closemutationprotecteddancers, election_candidates, election_votes, guideline_versions, moderator_elections, profile_members, profiles
election.pendingBookingsqueryprotectedbooking_requests, profile_members
election.moderateBookingmutationprotectedbooking_requests, profile_members
election.guidelineHistoryquerypublicguideline_versions
feedback.inquirymutationpublic—
feedback.reporterqueryprotecteddancers
gigs.listquerypublicgigs
gigs.getByIdquerypublicgigs
gigs.createmutationprotectedgigs
gigs.applyTomutationprotecteddancers, gig_applications, gigs, profile_members, profiles
gigs.myApplicationsqueryprotectedgig_applications, gigs
gigs.applicationsqueryprotecteddancers, gig_applications, gigs, profile_members, profiles
gigs.decideApplicationmutationprotecteddancers, gig_applications, gigs, profile_members
gigs.closemutationprotectedgigs
hangouts.listTonightquerypubliccities, events, hangout_rsvps, hangouts, plan_items
hangouts.listByEventquerypublichangout_rsvps, hangouts
hangouts.eventOptionsqueryprotectedcities, events, plan_items
hangouts.placeSearchqueryprotectedcities, hangouts
hangouts.placeDetailsqueryprotectedhangouts
hangouts.createmutationprotectedcities, dancers, events, hangout_rsvps, hangouts
hangouts.toggleRsvpmutationprotectedhangout_rsvps, hangouts
hangouts.closemutationprotectedhangouts
events.byCityquerypublicevents
events.sameDaysquerypubliccities, events
events.statsquerypubliccities, events
events.byProfilequerypublicevents
events.getquerypublicevents
events.festivalsquerypublicdancers, events, festival_signups, festivals, plan_items
events.festivalquerypublicevents, plan_items, profile_invites, profile_members, profiles
plan.countquerypublicplan_items
plan.countBatchquerypublicplan_items
plan.listqueryprotectedplan_items
plan.listDetailedqueryprotectedplan_items
plan.addmutationprotectedattendances, dancer_goals, events, plan_items, tracked_link_actions, tracked_links
plan.updateMetadatamutationprotectedplan_items
plan.removemutationprotectedattendances, dancer_goals, events, plan_items
plan.goingListquerypublicdancers, festival_signups, festivals, plan_items
plan.myPlanqueryprotectedfestival_signups, festivals, plan_items
plan.sharedPlanquerypublicdancers, festival_signups, festivals, plan_items
plan.discoverqueryprotectedcities, dancers, discover_swipes, events, festivals, follows, plan_items
plan.discoverSwipemutationprotecteddiscover_swipes
plan.discoverUnswipemutationprotecteddiscover_swipes
plan.weekSocialsqueryprotectedcities, dancers, events, follows, plan_items
plan.myCoursesqueryprotectedevents, plan_items
plan.goingBatchquerypublicdancers, plan_items
plan.setShareGoingmutationprotectedplan_items
plan.getShareGoingqueryprotectedplan_items
plan.proofShowcasequerypublicdancers, events, festivals, plan_items
plan.suggestionsquerypublicfestivals, plan_items
referral.validatequerypublicdancers
referral.myReferralsquerypublicfestivals, referrals
referral.trackVisitmutationpublictracked_link_actions, tracked_links
referral.myLinkmutationprotectedevents, profile_members, profiles, tracked_link_actions, tracked_links
referral.myResultsqueryprotectedevents, profile_members, profiles, tracked_link_actions, tracked_links
referral.eventLinkResultsqueryprotectedevents, profile_members, profiles, tracked_link_actions, tracked_links
referral.promoterDashboardqueryprotectedevents, giveaway_proposals, network_links, profile_members, profiles, tracked_link_actions, tracked_links
referral.promoKitmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles, tracked_links
rideShare.listquerypublicdancers, festival_ride_shares, festivals
rideShare.createmutationprotectedevents, festival_ride_shares, festivals
rideShare.deletemutationprotectedfestival_ride_shares, festivals
follow.togglemutationprotectedfollows
follow.toggleDancermutationprotectedfollows
follow.isFollowingqueryprotectedfollows
follow.isFollowingDancerqueryprotectedfollows
follow.areFriendsqueryprotectedfollows
follow.myFollowsqueryprotectedfollows, profiles
follow.countquerypublicfollows
business.canManagequerypublicprofile_members, profiles
business.myProfilesqueryprotectedprofile_claims, profile_members, profiles
business.searchqueryprotectedprofiles
business.requestClaimmutationprotectedprofile_access_log, profile_claims, profile_members, profiles
business.findExistingqueryprotectedprofiles
business.createmutationprotectedcities, dancers, profile_access_log, profile_members, profiles
business.getqueryprotectedprofile_members, profiles
business.spacesqueryprotectedbookable_spaces, profile_members, profiles
business.saveSpacesmutationprotectedbookable_spaces, booking_requests, profile_members, profiles
business.updatemutationprotectedcities, events, profile_members, profiles
businessEvents.listqueryprotectedevents, profile_members, profiles
businessEvents.canEditquerypublicevents, profile_members, profiles
businessEvents.getqueryprotectedevents, profile_members, profiles
businessEvents.createmutationprotectedcities, events, profile_members, profiles
businessEvents.updatemutationprotectedcities, events, profile_members, profiles
businessEvents.duplicatemutationprotectedevents, profile_members, profiles
businessEvents.seriesPreviewqueryprotectedcities, profile_members, profiles
businessEvents.createSeriesmutationprotectedcities, events, profile_members, profiles
businessEvents.seriesqueryprotectedevents, profile_members, profiles
businessEvents.publishSeriesmutationprotectedevents, profile_members, profiles
businessEvents.attendeesqueryprotectedattendances, dancers, events, festival_signups, festivals, plan_items, profile_members, profiles
businessEvents.restoremutationprotectedevents, profile_members, profiles
businessEvents.archivemutationprotectedevents, profile_members, profiles
businessEvents.lineupPhotosqueryprotectedprofiles
businessEvents.venueIdeasqueryprotectedcities, events, profiles
businessEvents.searchProfilesqueryprotectedprofiles
businessEvents.addFromInstagrammutationprotectedprofiles
businessEvents.inboxqueryprotectedbooking_inquiries, dancers, event_flyers, event_posts, events, profile_claims, profile_invites, profile_members, profile_suggestions, profiles
businessFlyers.captionqueryprotectedevents, profile_members, profiles
businessFlyers.writeCaptionmutationprotectedai_usage, events, profile_members, profiles
businessFlyers.saveCaptionmutationprotectedevents, profile_members, profiles
businessFlyers.statequeryprotectedbrand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.readLookmutationprotectedai_usage, events, profile_members, profiles
businessFlyers.makemutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.directionsmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.stopmutationprotectedevent_flyers, events, profile_members, profiles
businessFlyers.againmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.feedmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.fixmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.refreshmutationprotectedai_usage, brand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.batchqueryprotectedevent_flyers, events, profile_members, profiles
businessFlyers.keepmutationprotectedbrand_looks, event_flyers, event_posts, events, profile_members, profiles
businessFlyers.copyLooksmutationprotectedbrand_looks, profile_members, profiles
artistInvites.suggestmutationprotectedcities, events, profile_members, profile_suggestions, profiles
artistInvites.pendingqueryprotectedevents, profile_invites, profile_members, profile_suggestions, profiles
artistInvites.profilequeryprotectedevents, profile_members, profile_suggestions, profiles
artistInvites.saveProfilemutationprotectedcities, events, profile_members, profile_suggestions, profiles
artistInvites.linkmutationprotectedevents, profile_invites, profile_members, profiles
artistInvites.notifymutationprotecteddancers, events, profile_invites, profile_members, profiles
artistInvites.getquerypublicevent_flyers, events, plan_items, profile_invites, profile_members, profile_suggestions, profiles
artistInvites.respondmutationpubliccities, profile_invites, profile_members, profile_suggestions, profiles
artistInvites.claimmutationprotectedprofile_access_log, profile_invites, profile_members, profiles
venueAsks.askmutationprotectedevents, profile_invites, profile_members, profiles
venueAsks.listqueryprotectedevents, profile_invites, profile_members, profiles
venueAsks.bookmutationprotectedevents, profile_invites, profile_members, profiles
venueAsks.unbookmutationprotectedevents, profile_invites, profile_members, profiles
inquiries.mequeryprotecteddancers, events, profile_members, profiles
inquiries.addToEventmutationprotectedevents, profile_members, profiles
inquiries.sendmutationpublicbooking_inquiries, dancers, profile_members, profiles
inquiries.forProfilequeryprotectedbooking_inquiries, profile_members, profiles
inquiries.setStatusmutationprotectedbooking_inquiries, profile_members, profiles
businessPosts.listqueryprotectedevent_flyers, event_posts, events, profile_invites, profile_members, profiles
businessPosts.writeCaptionmutationprotectedai_usage, event_posts, events, profile_members, profiles
businessPosts.saveCaptionmutationprotectedevent_posts, events, profile_members, profiles
businessPosts.writeCaptionsmutationprotectedai_usage, event_posts, events, profile_members, profiles
businessPosts.proposemutationprotectedevent_posts, events, profile_members, profiles
businessPosts.addmutationprotectedevent_posts, events, profile_members, profiles
businessPosts.updatemutationprotectedevent_posts, events, profile_members, profiles
businessPosts.removemutationprotectedevent_posts, events, profile_members, profiles
businessLooks.listqueryprotectedbrand_looks, event_flyers, events, profile_members, profiles
businessLooks.createmutationprotectedbrand_looks, events, profile_members, profiles
businessLooks.updatemutationprotectedbrand_looks, profile_members, profiles
businessLooks.removemutationprotectedbrand_looks, profile_members, profiles
businessLooks.readmutationprotectedai_usage, brand_looks, events, profile_members, profiles
businessLooks.generatemutationprotectedai_usage, brand_looks, events, profile_members, profiles
businessSite.getqueryprotectedprofile_members, profile_sites, profiles
businessSite.savemutationprotectedprofile_members, profile_sites, profiles
businessSite.contactsqueryprotectedprofile_contacts, profile_members, profiles
businessSite.updateContactmutationprotectedprofile_contacts, profile_members, profiles
businessSite.removeContactmutationprotectedprofile_contacts, profile_members, profiles
businessTeam.requestAccessmutationprotectedprofile_access_log, profile_claims, profile_members, profiles
businessTeam.teamqueryprotecteddancers, profile_claims, profile_members, profiles
businessTeam.decideJoinmutationprotecteddancers, profile_access_log, profile_claims, profile_members, profiles
businessTeam.setRolemutationprotectedprofile_access_log, profile_members, profiles
businessTeam.removeMembermutationprotectedprofile_access_log, profile_members, profiles
businessTeam.historyqueryprotecteddancers, profile_access_log, profile_members, profiles
businessNetwork.listqueryprotectednetwork_links, profile_members, profiles
businessNetwork.addmutationprotectednetwork_links, profile_members, profiles
businessNetwork.hidemutationprotectednetwork_links, profile_members, profiles
businessNetwork.restoremutationprotectednetwork_links, profile_members, profiles
roommate.listquerypublicdancers, festival_roommate_lookups, festivals
roommate.togglemutationprotectedevents, festival_roommate_lookups, festivals
wave.sendmutationprotectedfestival_waves
wave.retractmutationprotectedfestival_waves
wave.myWavesqueryprotectedfestival_waves
wave.wavesForMequeryprotecteddancers, festival_waves
wave.friendsqueryprotecteddancers, festival_waves
wave.discoverPoolqueryprotecteddancers, festival_waves, plan_items
wave.incomingCountqueryprotectedfestival_waves
organizerSubscription.getStatusquerypublicorganizer_subscriptions
organizerSubscription.createCheckoutmutationprotecteddancers, organizer_subscriptions, profile_members, profiles
attendance.setmutationprotectedattendances, events
attendance.minequeryprotectedattendances
attendance.setVisibilitymutationprotectedattendances
attendance.updateLogisticsmutationprotectedattendances
attendance.publicListquerypublicattendances, dancers
attendance.countsquerypublicattendances, dancers
attendance.proofShowcasequerypublicattendances, dancers, events
attendance.checkInmutationprotectedattendances, events, profile_members
oauth.authorizeInfoquerypublicdancers, oauth_clients, profile_members, profiles
oauth.approvemutationprotectedoauth_clients, oauth_codes, oauth_grants, profile_members
oauth.denymutationprotected—
oauth.connectionsqueryprotectedoauth_clients, oauth_grants, profiles
oauth.revokeConnectionmutationprotectedoauth_grants, oauth_tokens
oauth.auditForProfilequeryprotecteddancers, mcp_audit, oauth_clients, profile_members, profiles

REST & webhook handlers

Nitro routes under server/api. Method and path come from the file name; purpose from the file's leading comment.

RouteAuthPurposeTables
ANY/.well-known/oauth-authorization-serversession— (no leading comment in the file)—
ANY/.well-known/oauth-protected-resourcepublic— (no leading comment in the file)—
ANY/.well-known/oauth-protected-resource/**public— (no leading comment in the file)—
GET/api/architecture/adminadminThe admin-only half of the generated API catalog (admin-level tRPC procedures, the tables they touch, admin procedures referenced by stories). Kept out of the public /docs/architecture bundle on purpose; served only to an `is_admin` dancer, using the same Bearer-session check as the tRPC adminProcedure. Generated by scripts/architecture/generate.ts into server/assets.dancers, oauth_grants, oauth_tokens, sessions
GET/api/citiespublicSSR-friendly cities directory. Mirrors trpc entity.listCities but lives as a plain Nitro route so the /cities page can fetch it with useFetch during SSR (the tRPC client is client-only, which is why /cities used to flash a spinner on mount). Cities arrive already rendered in the HTML — instant load.profiles
GET/api/cities/:slugpublicSSR-friendly city directory. Mirrors trpc entity.cityDirectory but as a plain Nitro route so /cities/[city] can render its people + an intent-first, data-driven <title> during SSR (the tRPC client is client-only).profiles
GET/api/city-optionspublicThe known-city list for <CityCombobox>: fetched once per session on first focus, filtered on the client with every keystroke (no request per letter), and its biggest communities are the "Popular on WeDance" empty state.cities, profiles
POST/api/city-resolvepublicTurns a picked Google suggestion into the canonical city: returns our row if we have it (no Google call), otherwise Place Details (English, + local language once per new city), upserts it into `cities` and returns it. `query` — what the person typed — is remembered as a spelling ("Мюнхен" → Munich). Before migration 0024 the city is returned with `persisted: false`.cities, profiles
GET/api/city-searchpublicOur canonical `cities` table first (accent/case-insensitive, alt names), then — only when that finds fewer than 3 cities and the query has 2+ letters — Google Places Autocomplete (types=(cities), English). Predictions for places we already have come back as our rows; the rest carry `source: 'google'` and must go through POST /api/city-resolve before they can be saved. `session` is the Places session token (one per typing session, client-made).cities, profiles
GET/api/contacts/unsubscribepublicThe unsubscribe link in a site's welcome email (RAZ-412). The id is the secret.profile_contacts, profiles
GET/api/event-statuspublicpublished event (or booking request) behind it. The event page calls this during SSR so a missing or unpublished event answers HTTP 404 instead of an empty 200 (the page itself loads its data in the browser).booking_requests, events
GET/api/festivalspublicSSR-friendly festivals directory for /festivals (useFetch during SSR, no spinner on mount).dancers, events, festival_signups, festivals, plan_items
GET/api/festivals/:slugpublicSingle-festival detail from the DB. Used by /festivals/[slug] as a fallback when the slug isn't in the hardcoded mock-data map, so DB-only festivals don't 404.festivals
GET/api/mcp-toolspublicThe MCP tool catalogue for the docs (/docs/mcp, /docs/connect-ai), straight from server/mcp/tools.ts so the docs never drift from the server.—
POST/api/media/imagepublic— (no leading comment in the file)—
ANY/api/profiles/:username/contactspublicSign-ups from a profile's own website (RAZ-412): the site's form posts here (cross-origin, so CORS is open) and the person becomes one of the profile's contacts on WeDance (/business/network/<username>/contacts). The team is emailed; the person gets the welcome email the profile wrote on WeDance. Signing up again with the same email updates the contact.dancers, profile_contacts, profile_members, profile_sites, profiles
GET/api/profiles/:username/eventspublicPublic feed of a profile's upcoming events, for the profile's own website (e.g. montuno.club reads /api/profiles/montunoclub/events). The events a profile runs (host) or organizes, published and not over, soonest first — so the website shows exactly what the profile shows on WeDance, and every row links back to WeDance for sign-up.events, profiles
GET/api/profiles/:username/sitepublicA profile's website in one language (RAZ-412): its sections and words as edited on WeDance (/business/network/<username>/website), plus the upcoming events the page's "events" sections list. The site renders this and nothing else, so changing the page is changing it here.events, profile_sites, profiles
GET/api/qr/:filepublicThe QR code of a promoter's tracked link: /api/qr/<code>.svg or .png (promo_kit, my_link). Only for codes that exist, so this is not an open QR generator; the code always points at the event on our own origin.events, tracked_links
POST/api/stripe/webhooksignature`server_subscription_cancelled`, once per organiser subscription: only while our row is not yet 'canceled' (call BEFORE the status update), so a Stripe redelivery or an `updated` + `deleted` pair counts one cancellation. A subscription we have no row for (another product on the account) is skipped.dancers, events, festival_signups, festivals, organizer_subscriptions, referrals, tracked_link_actions, tracked_links
ANY/api/trpc/:trpcsessiontRPC endpoint — dispatches every procedure in the API catalog below.—
POST/api/webhooks/tickettailorsignatureTicketTailor webhook receiver.dancers, festival_signups, festivals
ANY/mcppublic— (no leading comment in the file)ai_usage, attendances, availability_slots, bookable_spaces, booking_inquiries, booking_requests, brand_looks, cities, city_battle_votes, city_videos, community_group_reports, community_groups, dancer_goals, dancers, dinner_group_members, dinner_groups, dinner_signups, dinners, discover_swipes, election_candidates, election_vote_history, election_votes, event_flyers, event_posts, events, festival_ride_shares, festival_roommate_lookups, festival_signups, festival_submissions, festival_waves, festivals, follows, gig_applications, gigs, giveaway_entries, giveaway_proposals, giveaways, guideline_versions, hangout_rsvps, hangouts, mcp_audit, mcp_rate_limits, moderator_elections, network_links, oauth_clients, oauth_codes, oauth_grants, oauth_tokens, organizer_subscriptions, plan_items, profile_access_log, profile_claims, profile_contacts, profile_invites, profile_members, profile_sites, profile_suggestions, profiles, recommendation_requests, referrals, reviews, sessions, tracked_link_actions, tracked_links, video_votes
ANY/mcp/publicpublic— (no leading comment in the file)ai_usage, attendances, availability_slots, bookable_spaces, booking_inquiries, booking_requests, brand_looks, cities, city_battle_votes, city_videos, community_group_reports, community_groups, dancer_goals, dancers, dinner_group_members, dinner_groups, dinner_signups, dinners, discover_swipes, election_candidates, election_vote_history, election_votes, event_flyers, event_posts, events, festival_ride_shares, festival_roommate_lookups, festival_signups, festival_submissions, festival_waves, festivals, follows, gig_applications, gigs, giveaway_entries, giveaway_proposals, giveaways, guideline_versions, hangout_rsvps, hangouts, mcp_audit, mcp_rate_limits, moderator_elections, network_links, oauth_clients, oauth_codes, oauth_grants, oauth_tokens, organizer_subscriptions, plan_items, profile_access_log, profile_claims, profile_contacts, profile_invites, profile_members, profile_sites, profile_suggestions, profiles, recommendation_requests, referrals, reviews, sessions, tracked_link_actions, tracked_links, video_votes
ANY/oauth/registerpublic— (no leading comment in the file)mcp_rate_limits, oauth_clients
ANY/oauth/revokesession— (no leading comment in the file)mcp_rate_limits, oauth_clients, oauth_grants, oauth_tokens
ANY/oauth/tokensession— (no leading comment in the file)mcp_rate_limits, oauth_clients, oauth_codes, oauth_grants, oauth_tokens

REST auth is a static heuristic: signature = verifies a webhook signature, session = reads the Bearer session, admin = checks is_admin, public = none of those.