{"openapi":"3.1.0","info":{"title":"Tampa.dev Platform API","version":"1.0.0","description":"The Tampa.dev Platform API provides authenticated access to community data including user profiles, events, groups, badges, and more. Authenticate with Personal Access Tokens (PATs) or OAuth 2.0 bearer tokens. All authenticated endpoints are under `/v1/`.","contact":{"name":"Tampa.dev","url":"https://tampa.dev"}},"servers":[{"url":"https://api.tampa.dev","description":"Production"},{"url":"https://events.api.tampa.dev","description":"Production (legacy)"},{"url":"http://localhost:8787","description":"Development"}],"security":[{"BearerToken":[]}],"tags":[{"name":"User","description":"User identity and profile management"},{"name":"Events","description":"Event discovery, RSVP, and check-in"},{"name":"Groups","description":"Group discovery and favorites"},{"name":"Follows","description":"User follow relationships"},{"name":"Claims","description":"Badge claim links"},{"name":"Scopes","description":"OAuth scope discovery"},{"name":"Management","description":"Group management (group role required)"},{"name":"Developer","description":"OAuth application and webhook management"},{"name":"Uploads","description":"File upload management and storage"},{"name":"Onboarding","description":"User onboarding step management"},{"name":"MeetPass","description":"NFC and QR code passes for in-person connections"},{"name":"Public","description":"Public endpoints (no authentication required)"},{"name":"MCP","description":"Model Context Protocol (JSON-RPC 2.0) endpoint for AI agents and automation tools"}],"components":{"securitySchemes":{"BearerToken":{"type":"http","scheme":"bearer","description":"Personal Access Token (td_pat_...) or OAuth 2.0 access token. Create PATs at https://tampa.dev/developer. OAuth tokens are obtained via the /oauth/authorize flow."}},"schemas":{"OAuthApp":{"type":"object","properties":{"clientId":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"redirectUris":{"type":"array","items":{"type":"string"}},"website":{"type":["string","null"]},"logoUri":{"type":["string","null"]},"policyUri":{"type":["string","null"]},"tosUri":{"type":["string","null"]},"isPublicClient":{"type":"boolean"},"createdAt":{"type":["string","null"]},"activeUsers":{"type":"number"}},"required":["clientId","name","description","redirectUris","website","logoUri","policyUri","tosUri","isPublicClient","createdAt"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["error","code"]},"OAuthAppCreated":{"allOf":[{"$ref":"#/components/schemas/OAuthApp"},{"type":"object","properties":{"clientSecret":{"type":"string","description":"Client secret. Store securely — it cannot be retrieved again."}},"required":["clientSecret"]}]},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"secret":{"type":"string"},"createdAt":{"type":["string","null"]}},"required":["id","url","eventTypes","isActive","createdAt"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"eventType":{"type":"string"},"statusCode":{"type":["number","null"]},"success":{"type":"boolean"},"deliveredAt":{"type":["string","null"]}},"required":["id","eventType","statusCode","success","deliveredAt"]},"WebhookTestResult":{"type":"object","properties":{"success":{"type":"boolean"},"statusCode":{"type":["number","null"]},"responseBody":{"type":["string","null"]}},"required":["success","statusCode","responseBody"]},"UploadRequestResponse":{"type":"object","properties":{"key":{"type":"string"},"uploadUrl":{"type":"string"},"publicUrl":{"type":"string"}},"required":["key","uploadUrl","publicUrl"]},"UploadRequest":{"type":"object","properties":{"category":{"type":"string","enum":["avatar","app-logo","media","hero","group-photo","event-photo","meetpass-image","meetpass-model"],"description":"Upload category"},"filename":{"type":"string","minLength":1,"maxLength":255,"description":"Original filename"},"contentType":{"type":"string","enum":["image/jpeg","image/png","image/gif","image/webp","model/gltf-binary","application/octet-stream"],"description":"MIME content type"},"size":{"type":"number","exclusiveMinimum":0,"maximum":10485760,"description":"File size in bytes (max 10MB)"}},"required":["category","filename","contentType","size"]},"Upload":{"type":"object","properties":{"key":{"type":"string"},"category":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"size":{"type":"number"},"createdAt":{"type":["string","null"]}},"required":["key","category","filename","contentType","size","createdAt"]},"Pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items (may be absent if count is expensive)"},"limit":{"type":"number","description":"Maximum items per page"},"offset":{"type":"number","description":"Number of items skipped (present in offset mode only)"},"hasMore":{"type":"boolean","description":"Whether more items exist beyond this page"},"nextCursor":{"type":"string","description":"Opaque cursor to pass as ?cursor= for the next page (present in cursor mode)"},"prevCursor":{"type":"string","description":"Opaque cursor to pass as ?before= for the previous page (present in cursor mode)"}},"required":["limit","hasMore"]},"StorageUsage":{"type":"object","properties":{"totalSize":{"type":"number"},"fileCount":{"type":"number"},"byCategory":{"type":"object","additionalProperties":{"type":"object","properties":{"size":{"type":"number"},"count":{"type":"number"}},"required":["size","count"]}}},"required":["totalSize","fileCount","byCategory"]},"OnboardingStep":{"type":"object","properties":{"key":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"completed":{"type":"boolean"},"dismissedAt":{"type":["string","null"]}},"required":["key","title","description","completed","dismissedAt"]},"McpError":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}},"required":["error","code"]},"GroupDetail":{"allOf":[{"$ref":"#/components/schemas/GroupListItem"},{"type":"object","properties":{"upcomingEvents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"dateTime":{"type":"string"},"eventUrl":{"type":["string","null"],"description":"Canonical Tampa.dev URL for this event"},"platformEventUrl":{"type":["string","null"],"description":"Original URL on the source platform, or null for native events"}},"required":["id","title","dateTime","eventUrl","platformEventUrl"]}}},"required":["upcomingEvents"]}]},"GroupListItem":{"type":"object","properties":{"id":{"type":"string"},"urlname":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":["string","null"]},"link":{"type":["string","null"]},"website":{"type":["string","null"]},"memberCount":{"type":["number","null"]},"photoUrl":{"type":["string","null"]},"tags":{},"socialLinks":{},"isFeatured":{"type":["boolean","null"]},"favoritesCount":{"type":"number"}},"required":["id","urlname","name","description","link","website","memberCount","photoUrl","isFeatured","favoritesCount"]},"EventDetail":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"dateTime":{"type":"string"},"endTime":{"type":["string","null"]},"timezone":{"type":["string","null"]},"duration":{"type":["string","null"]},"eventUrl":{"type":["string","null"],"description":"Canonical Tampa.dev URL for this event"},"platformEventUrl":{"type":["string","null"],"description":"Original URL on the source platform (Meetup, Eventbrite, Luma), or null for native events"},"photoUrl":{"type":["string","null"]},"eventType":{"type":["string","null"]},"rsvpCount":{"type":["number","null"],"description":"Cumulative RSVP count (on-platform + upstream). Use this as the displayed total."},"localRsvpCount":{"type":"number","description":"On-platform RSVPs only (rows in event_rsvps)."},"upstreamRsvpCount":{"type":["number","null"],"description":"Upstream-reported RSVP count from the source provider. Null when the provider does not expose a count (Eventbrite, Luma); distinct from 0."},"maxAttendees":{"type":["number","null"]},"source":{"type":"string"},"group":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"venue":{"type":["object","null"],"properties":{"name":{"type":"string"},"address":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]},"isOnline":{"type":["boolean","null"]}},"required":["name","address","city","state","latitude","longitude","isOnline"]}},"required":["id","title","description","dateTime","endTime","timezone","duration","eventUrl","platformEventUrl","photoUrl","eventType","rsvpCount","localRsvpCount","upstreamRsvpCount","maxAttendees","source","group","venue"]},"UserBasic":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"avatarUrl":{"type":["string","null"]},"username":{"type":["string","null"]},"email":{"type":"string"},"lastLoginAt":{"type":["string","null"]}},"required":["id","name","avatarUrl","username","lastLoginAt"]},"UserProfile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"username":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"heroImageUrl":{"type":["string","null"]},"themeColor":{"type":["string","null"]},"bio":{"type":["string","null"]},"location":{"type":["string","null"]},"socialLinks":{"type":["array","null"],"items":{"type":"string"}},"role":{"type":"string"},"profileVisibility":{"type":"string","enum":["public","private"]},"showOnLeaderboard":{"type":["boolean","null"]},"createdAt":{"type":"string"},"email":{"type":"string"}},"required":["id","name","username","avatarUrl","heroImageUrl","themeColor","bio","location","socialLinks","role","profileVisibility","showOnLeaderboard","createdAt"]},"UpdateProfileRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"avatarUrl":{"type":["string","null"],"format":"uri"},"heroImageUrl":{"type":["string","null"],"format":"uri"},"themeColor":{"type":["string","null"],"enum":["coral","ocean","sunset","forest","violet","rose","slate","sky",null]},"username":{"type":"string","minLength":3,"maxLength":30,"pattern":"^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$"},"bio":{"type":["string","null"],"maxLength":500},"location":{"type":["string","null"],"maxLength":100},"socialLinks":{"type":["array","null"],"items":{"type":"string","format":"uri"},"maxItems":5},"showOnLeaderboard":{"type":"boolean"},"profileVisibility":{"type":"string","enum":["public","private"]}}},"LinkedAccount":{"type":"object","properties":{"provider":{"type":"string"},"providerUsername":{"type":["string","null"]},"providerEmail":{"type":["string","null"]},"createdAt":{"type":["string","null"]}},"required":["provider","providerUsername","providerEmail","createdAt"]},"UsernameCheck":{"type":"object","properties":{"available":{"type":"boolean"},"reason":{"type":"string"}},"required":["available"]},"OAuthGrant":{"type":"object","properties":{"grantId":{"type":"string"},"clientId":{"type":"string"},"clientName":{"type":"string"},"clientUri":{"type":["string","null"]},"logoUri":{"type":["string","null"]},"scopes":{},"grantedAt":{"type":"string"}},"required":["grantId","clientId","clientName","grantedAt"]},"PortfolioItem":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"url":{"type":["string","null"]},"imageUrl":{"type":["string","null"]},"sortOrder":{"type":"number"},"createdAt":{"type":["string","null"]}},"required":["id","userId","title","description","url","imageUrl","sortOrder","createdAt"]},"PortfolioItemRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":["string","null"],"maxLength":500},"url":{"type":["string","null"],"format":"uri"},"imageUrl":{"type":["string","null"],"format":"uri"},"sortOrder":{"type":"integer","minimum":0,"default":0}},"required":["title"]},"PortfolioItemUpdateRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":["string","null"],"maxLength":500},"url":{"type":["string","null"],"format":"uri"},"imageUrl":{"type":["string","null"],"format":"uri"},"sortOrder":{"type":"integer","minimum":0,"default":0}}},"AchievementProgress":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":["string","null"]},"color":{"type":["string","null"]},"targetValue":{"type":"number"},"currentValue":{"type":"number"},"completedAt":{"type":["string","null"]},"badgeSlug":{"type":["string","null"]},"hidden":{"type":"boolean"}},"required":["key","name","description","icon","color","targetValue","currentValue","completedAt","badgeSlug","hidden"]},"UserBadge":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":"string"},"iconUrl":{"type":["string","null"],"description":"URL to the high-quality emoji image, or null if unavailable"},"color":{"type":"string"},"points":{"type":"number"},"awardedAt":{"type":["string","null"]},"group":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"rarity":{"type":"object","properties":{"tier":{"type":"string","enum":["common","uncommon","rare","epic","legendary"]},"percentage":{"type":"number"}},"required":["tier","percentage"]}},"required":["name","slug","description","icon","iconUrl","color","points","awardedAt","group","rarity"]},"UserEntitlement":{"type":"object","properties":{"id":{"type":"string"},"entitlement":{"type":"string","description":"Entitlement key (e.g., dev.tampa.group.create)"},"grantedAt":{"type":["string","null"],"description":"ISO timestamp when entitlement was granted"},"expiresAt":{"type":["string","null"],"description":"ISO timestamp when entitlement expires, or null if permanent"},"source":{"type":["string","null"],"description":"How the entitlement was granted (e.g., admin, achievement)"}},"required":["id","entitlement","grantedAt","expiresAt","source"]},"Token":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"tokenPrefix":{"type":"string"},"scopes":{"type":"string"},"expiresAt":{"type":["string","null"]},"createdAt":{"type":["string","null"]},"lastUsedAt":{"type":["string","null"]}},"required":["id","name","tokenPrefix","scopes","expiresAt","createdAt","lastUsedAt"]},"TokenCreated":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token":{"type":"string","description":"Full token value. Store securely — it cannot be retrieved again."},"tokenPrefix":{"type":"string"},"scopes":{"type":"string"},"expiresAt":{"type":["string","null"]},"createdAt":{"type":["string","null"]}},"required":["id","name","token","tokenPrefix","scopes","expiresAt","createdAt"]},"CreateTokenRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-readable name for the token"},"scopes":{"type":"array","items":{"type":"string"},"minItems":1,"description":"OAuth scopes to grant to this token"},"expiresInDays":{"type":"integer","minimum":1,"maximum":365,"description":"Token expiry in days (1-365, default: no expiry)"}},"required":["name","scopes"]},"FeedToken":{"type":"object","properties":{"feedToken":{"type":"string","description":"Personal feed token for RSS/iCal URLs"}},"required":["feedToken"]},"EventListItem":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"dateTime":{"type":"string"},"endTime":{"type":["string","null"]},"timezone":{"type":["string","null"]},"eventUrl":{"type":["string","null"],"description":"Canonical Tampa.dev URL for this event"},"platformEventUrl":{"type":["string","null"],"description":"Original URL on the source platform (Meetup, Eventbrite, Luma), or null for native events"},"photoUrl":{"type":["string","null"]},"eventType":{"type":["string","null"]},"rsvpCount":{"type":["number","null"],"description":"Cumulative RSVP count (on-platform + upstream). Use this as the displayed total."},"localRsvpCount":{"type":"number","description":"On-platform RSVPs only (rows in event_rsvps)."},"upstreamRsvpCount":{"type":["number","null"],"description":"Upstream-reported RSVP count from the source provider. Null when the provider does not expose a count (Eventbrite, Luma); distinct from 0."},"maxAttendees":{"type":["number","null"]},"group":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]}},"required":["id","name","urlname"]}},"required":["id","title","description","dateTime","endTime","timezone","eventUrl","platformEventUrl","photoUrl","eventType","rsvpCount","localRsvpCount","upstreamRsvpCount","maxAttendees","group"]},"RsvpStatusResponse":{"type":"object","properties":{"rsvp":{"$ref":"#/components/schemas/Rsvp"}},"required":["rsvp"]},"Rsvp":{"type":["object","null"],"properties":{"id":{"type":"string"},"eventId":{"type":"string"},"status":{"type":"string","enum":["confirmed","waitlisted","cancelled"]},"rsvpAt":{"type":["string","null"]},"waitlistPosition":{"type":["number","null"]}},"required":["id","eventId","status","rsvpAt","waitlistPosition"]},"RsvpSummary":{"type":"object","properties":{"total":{"type":"number"},"confirmed":{"type":"number"},"waitlisted":{"type":"number"},"cancelled":{"type":"number"},"capacity":{"type":["number","null"]}},"required":["total","confirmed","waitlisted","cancelled","capacity"]},"CheckinInfo":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":["string","null"]},"timezone":{"type":["string","null"]},"eventType":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","title","startTime","endTime","timezone","eventType","photoUrl"]},"group":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"checkinAvailable":{"type":"boolean"}},"required":["event","group","checkinAvailable"]},"CheckinResult":{"type":"object","properties":{"id":{"type":"string"},"eventId":{"type":"string"},"checkedInAt":{"type":"string"},"method":{"type":"string"}},"required":["id","eventId","checkedInAt","method"]},"GroupMember":{"type":"object","properties":{"username":{"type":["string","null"]},"name":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"favoritedAt":{"type":["string","null"]}},"required":["username","name","avatarUrl","favoritedAt"]},"FollowEntry":{"type":"object","properties":{"username":{"type":["string","null"]},"name":{"type":"string"},"avatarUrl":{"type":["string","null"]},"followedAt":{"type":["string","null"]}},"required":["username","name","avatarUrl","followedAt"]},"ConnectionEntry":{"type":"object","properties":{"username":{"type":["string","null"]},"name":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"connectedAt":{"type":["string","null"]}},"required":["username","name","avatarUrl","connectedAt"]},"BadgeCatalog":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":"string"},"iconUrl":{"type":["string","null"]},"color":{"type":"string"},"points":{"type":"number"},"sortOrder":{"type":"number"},"awardedCount":{"type":"number"},"rarity":{"type":"object","properties":{"tier":{"type":"string","enum":["common","uncommon","rare","epic","legendary"]},"percentage":{"type":"number"}},"required":["tier","percentage"]}},"required":["id","name","slug","description","icon","iconUrl","color","points","sortOrder","awardedCount","rarity"]},"BadgeDetail":{"allOf":[{"$ref":"#/components/schemas/BadgeCatalog"},{"type":"object","properties":{"createdAt":{"type":["string","null"]}},"required":["createdAt"]}]},"PublicUserList":{"type":"object","properties":{"username":{"type":"string"},"name":{"type":["string","null"]},"bio":{"type":["string","null"]},"location":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"themeColor":{"type":["string","null"]},"badges":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"icon":{"type":"string"},"color":{"type":"string"},"description":{"type":["string","null"]}},"required":["name","slug","icon","color","description"]}},"memberSince":{"type":["string","null"]}},"required":["username","name","bio","location","avatarUrl","themeColor","badges","memberSince"]},"PublicUserProfile":{"type":"object","properties":{"username":{"type":"string"},"name":{"type":["string","null"]},"bio":{"type":["string","null"]},"location":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"heroImageUrl":{"type":["string","null"]},"themeColor":{"type":["string","null"]},"socialLinks":{"type":["array","null"],"items":{"type":"string"}},"githubUsername":{"type":["string","null"]},"favoriteGroups":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"photoUrl":{"type":["string","null"]}},"required":["slug","name","photoUrl"]}},"badges":{"type":"array","items":{}},"groupBadges":{"type":"array","items":{}},"achievements":{"type":"array","items":{}},"portfolioItems":{"type":"array","items":{}},"xpScore":{"type":"number"},"followerCount":{"type":"number","description":"Number of followers"},"followingCount":{"type":"number","description":"Number of users this user follows"},"recentConnections":{"type":"array","items":{}},"memberSince":{"type":["string","null"]}},"required":["username","name","bio","location","avatarUrl","heroImageUrl","themeColor","socialLinks","githubUsername","favoriteGroups","badges","groupBadges","achievements","portfolioItems","xpScore","followerCount","followingCount","recentConnections","memberSince"]},"UserGroupBadges":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/GroupBadgeGroup"}}},"required":["groups"]},"GroupBadgeGroup":{"type":"object","properties":{"group":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":"string"},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"badges":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"icon":{"type":"string"},"color":{"type":"string"},"description":{"type":["string","null"]},"points":{"type":"number"},"awardedAt":{"type":["string","null"]},"rarity":{"type":"object","properties":{"tier":{"type":"string"},"percentage":{"type":"number"}},"required":["tier","percentage"]}},"required":["name","slug","icon","color","description","points","awardedAt","rarity"]}},"xpSubtotal":{"type":"number"}},"required":["group","badges","xpSubtotal"]},"GlobalLeaderboard":{"type":"object","properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/LeaderboardEntry"}},"total":{"type":"number"},"totalAchievements":{"type":"number"}},"required":["entries","total","totalAchievements"]},"LeaderboardEntry":{"type":"object","properties":{"rank":{"type":"number"},"username":{"type":"string"},"name":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"score":{"type":"number"},"completedCount":{"type":"number"},"badgeCount":{"type":"number"},"badges":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"icon":{"type":"string"},"color":{"type":"string"}},"required":["name","slug","icon","color"]}}},"required":["rank","username","name","avatarUrl","score","badges"]},"GroupLeaderboard":{"type":"object","properties":{"group":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"entries":{"type":"array","items":{"$ref":"#/components/schemas/LeaderboardEntry"}},"total":{"type":"number"}},"required":["group","entries","total"]},"LeaderboardMovers":{"type":"object","properties":{"period":{"type":"object","properties":{"start":{"type":"string"},"end":{"type":"string"},"label":{"type":"string"}},"required":["start","end","label"]},"movers":{"type":"array","items":{"$ref":"#/components/schemas/LeaderboardMover"}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"}},"required":["period","movers","total","limit","offset"]},"LeaderboardMover":{"type":"object","properties":{"username":{"type":"string"},"name":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"currentXp":{"type":"number"},"xpGained":{"type":"number"},"currentRank":{"type":"number"},"previousRank":{"type":["number","null"]},"rankChange":{"type":["number","null"]},"badgesEarned":{"type":"number"},"isNewUser":{"type":"boolean"}},"required":["username","name","avatarUrl","currentXp","xpGained","currentRank","previousRank","rankChange","badgesEarned","isNewUser"]},"GroupClaimInvite":{"type":"object","properties":{"group":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["id","name","urlname","photoUrl"]},"autoApprove":{"type":["boolean","null"]},"claimable":{"type":"boolean"}},"required":["group","autoApprove","claimable"]},"GroupClaimResult":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"string","enum":["approved","pending"]},"message":{"type":"string"},"requestId":{"type":"string"}},"required":["success","status","message"]},"ClaimInfo":{"type":"object","properties":{"badge":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":"string"},"iconUrl":{"type":["string","null"],"description":"URL to the high-quality emoji image, or null if unavailable"},"color":{"type":["string","null"]},"points":{"type":"number"}},"required":["name","slug","description","icon","iconUrl","color","points"]},"group":{"type":["object","null"],"properties":{"name":{"type":"string"},"urlname":{"type":["string","null"]},"photoUrl":{"type":["string","null"]}},"required":["name","urlname","photoUrl"]},"claimable":{"type":"boolean"},"reason":{"type":"string"}},"required":["badge","group","claimable"]},"ClaimBadgeResponse":{"type":"object","properties":{"badge":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":"string"},"iconUrl":{"type":["string","null"]},"color":{"type":"string"},"points":{"type":"number"}},"required":["name","slug","description","icon","iconUrl","color","points"]}},"required":["badge"]},"Scope":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"implies":{"type":"array","items":{"type":"string"}}},"required":["name","description","implies"]},"Meetpass":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"label":{"type":["string","null"]},"designId":{"type":["string","null"]},"action":{"type":["string","null"]},"autoFollow":{"type":"number"},"isActive":{"type":"number"},"claimedAt":{"type":["string","null"]},"createdAt":{"type":["string","null"]}},"required":["id","type","label","designId","action","autoFollow","isActive","claimedAt","createdAt"]},"MeetpassConnection":{"type":"object","properties":{"id":{"type":"string"},"connectedUserId":{"type":["string","null"]},"visitorAnonId":{"type":["string","null"]},"createdAt":{"type":["string","null"]},"direction":{"type":"string","enum":["inbound","outbound"]},"connectedName":{"type":["string","null"]},"connectedUsername":{"type":["string","null"]},"connectedAvatarUrl":{"type":["string","null"]}},"required":["id","connectedUserId","visitorAnonId","createdAt","direction","connectedName","connectedUsername","connectedAvatarUrl"]},"ManagedGroup":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"urlname":{"type":["string","null"]},"description":{"type":["string","null"]},"photoUrl":{"type":["string","null"]},"memberCount":{"type":["number","null"]},"userRole":{"type":"string"}},"required":["id","name","urlname","description","photoUrl","memberCount","userRole"]},"ManagedBadge":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":["string","null"]},"icon":{"type":"string"},"iconUrl":{"type":["string","null"]},"color":{"type":"string"},"points":{"type":"number"},"sortOrder":{"type":"number"},"createdAt":{"type":["string","null"]},"awardedCount":{"type":"number"}},"required":["id","name","slug","description","icon","iconUrl","color","points","sortOrder","createdAt"]},"ClaimLink":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"maxUses":{"type":["number","null"]},"currentUses":{"type":"number"},"expiresAt":{"type":["string","null"]},"createdAt":{"type":["string","null"]}},"required":["id","code","maxUses","currentUses","expiresAt","createdAt"]},"CheckinCode":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"label":{"type":["string","null"]},"maxUses":{"type":["number","null"]},"currentUses":{"type":"number"},"expiresAt":{"type":["string","null"]},"createdAt":{"type":["string","null"]}},"required":["id","code","label","maxUses","currentUses","expiresAt","createdAt"]}},"parameters":{}},"paths":{"/schemas":{"get":{"summary":"List all JSON schemas","description":"Returns metadata about all available JSON schemas for the API models","tags":["Schemas"],"responses":{"200":{"description":"List of available schemas","content":{"application/json":{"schema":{"type":"object","properties":{"schemas":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"}},"required":["name","title","description","url"]}},"version":{"type":"string"}},"required":["schemas","version"]}}}}}}},"/schemas/{name}":{"get":{"summary":"Get specific JSON schema","description":"Returns the JSON Schema for a specific model type","tags":["Schemas"],"parameters":[{"schema":{"type":"string","description":"Schema name (event, group, venue, photo, meetup)","example":"event"},"required":true,"description":"Schema name (event, group, venue, photo, meetup)","name":"name","in":"path"}],"responses":{"200":{"description":"JSON Schema","content":{"application/schema+json":{"schema":{}}}},"404":{"description":"Schema not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"available":{"type":"array","items":{"type":"string"}}},"required":["error","available"]}}}}}}},"/widget/next-event":{"get":{"summary":"Next event HTML widget","description":"Returns an HTML widget showing the next upcoming event","tags":["Widgets"],"parameters":[{"schema":{"type":"string","description":"Comma-separated list of group URL names to filter by","example":"tampadevs,suncoast-js"},"required":false,"description":"Comma-separated list of group URL names to filter by","name":"groups","in":"query"}],"responses":{"200":{"description":"HTML widget","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/widget/carousel":{"get":{"summary":"Carousel HTML widget","description":"Returns an HTML carousel widget showing upcoming events","tags":["Widgets"],"parameters":[{"schema":{"type":"string","description":"Comma-separated list of group URL names to filter by","example":"tampadevs,suncoast-js"},"required":false,"description":"Comma-separated list of group URL names to filter by","name":"groups","in":"query"}],"responses":{"200":{"description":"HTML carousel widget","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/v1/developer/apps":{"get":{"summary":"List OAuth applications","description":"Returns all OAuth applications owned by the authenticated user.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"responses":{"200":{"description":"List of OAuth applications","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"apps":{"type":"array","items":{"$ref":"#/components/schemas/OAuthApp"}}},"required":["apps"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create an OAuth application","description":"Registers a new OAuth application. The client secret is returned once and cannot be retrieved again.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500},"redirectUris":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":10},"website":{"type":"string","format":"uri"},"logoUri":{"type":"string","format":"uri"},"policyUri":{"type":"string","format":"uri"},"tosUri":{"type":"string","format":"uri"},"isPublicClient":{"type":"boolean","default":false}},"required":["name","redirectUris"]}}}},"responses":{"201":{"description":"Created OAuth application with client secret","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OAuthAppCreated"}},"required":["data"]}}}},"400":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/apps/{clientId}":{"get":{"summary":"Get an OAuth application","description":"Returns details for a specific OAuth application owned by the authenticated user.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"OAuth client ID","example":"abc123"},"required":true,"description":"OAuth client ID","name":"clientId","in":"path"}],"responses":{"200":{"description":"OAuth application details","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OAuthApp"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"summary":"Update an OAuth application","description":"Updates fields on an OAuth application owned by the authenticated user.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"OAuth client ID","example":"abc123"},"required":true,"description":"OAuth client ID","name":"clientId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":"string","maxLength":500},"redirectUris":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":10},"website":{"type":"string","format":"uri"},"logoUri":{"type":"string","format":"uri"},"policyUri":{"type":"string","format":"uri"},"tosUri":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Updated OAuth application","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OAuthApp"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete an OAuth application","description":"Permanently deletes an OAuth application and revokes all associated tokens.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"OAuth client ID","example":"abc123"},"required":true,"description":"OAuth client ID","name":"clientId","in":"path"}],"responses":{"200":{"description":"Application deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/apps/{clientId}/regenerate-secret":{"post":{"summary":"Regenerate client secret","description":"Regenerates the client secret for an OAuth application. The new secret is returned once and cannot be retrieved again.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"OAuth client ID","example":"abc123"},"required":true,"description":"OAuth client ID","name":"clientId","in":"path"}],"responses":{"200":{"description":"Regenerated client secret","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"clientId":{"type":"string"},"clientSecret":{"type":"string"},"message":{"type":"string"}},"required":["clientId","clientSecret","message"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/webhooks":{"get":{"summary":"List webhooks","description":"Returns all webhooks configured by the authenticated user.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"responses":{"200":{"description":"List of webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}},"required":["webhooks"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create a webhook","description":"Registers a new webhook endpoint for receiving event notifications.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"eventTypes":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"default":["*"]}},"required":["url"]}}}},"responses":{"201":{"description":"Created webhook","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/webhooks/{id}":{"patch":{"summary":"Update a webhook","description":"Updates configuration for an existing webhook.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"eventTypes":{"type":"array","items":{"type":"string","minLength":1},"minItems":1},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated webhook","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete a webhook","description":"Permanently deletes a webhook.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/webhooks/{id}/deliveries":{"get":{"summary":"List webhook deliveries","description":"Returns recent delivery attempts for a specific webhook.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"responses":{"200":{"description":"List of webhook deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}},"required":["deliveries"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/developer/webhooks/{id}/test":{"post":{"summary":"Test a webhook","description":"Sends a test event to the webhook endpoint and returns the result.","tags":["Developer"],"security":[{"BearerToken":["developer"]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"eventType":{"type":"string"}}}}}},"responses":{"200":{"description":"Webhook test result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookTestResult"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/uploads/request":{"post":{"summary":"Request a presigned upload URL","description":"Returns a presigned URL for direct client-to-R2 upload. Also records the upload in the accounting table.","tags":["Uploads"],"security":[{"BearerToken":["write:uploads"]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequest"}}}},"responses":{"201":{"description":"Presigned upload URL","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UploadRequestResponse"}},"required":["data"]}}}},"400":{"description":"Bad Request — invalid input","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}},"required":["error","code"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/uploads":{"get":{"summary":"List uploads","description":"Lists the authenticated user's uploads with optional category filtering and pagination.","tags":["Uploads"],"security":[{"BearerToken":["read:uploads"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by upload category"},"required":false,"description":"Filter by upload category","name":"category","in":"query"}],"responses":{"200":{"description":"List of uploads","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Upload"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/uploads/usage":{"get":{"summary":"Get storage usage","description":"Returns storage usage statistics for the authenticated user, broken down by category.","tags":["Uploads"],"security":[{"BearerToken":["read:uploads"]}],"responses":{"200":{"description":"Storage usage statistics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/StorageUsage"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/uploads/{key}":{"delete":{"summary":"Delete an uploaded file","description":"Deletes a file from storage. The key is the full R2 object key. Only the owner or an admin can delete.","tags":["Uploads"],"security":[{"BearerToken":["write:uploads"]}],"parameters":[{"schema":{"type":"string","description":"R2 object key (may contain path separators)"},"required":true,"description":"R2 object key (may contain path separators)","name":"key","in":"path"}],"responses":{"200":{"description":"File deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/uploads/file/{key}":{"get":{"summary":"Serve an uploaded file","description":"Public endpoint that serves an uploaded file by its R2 key. No authentication required.","tags":["Uploads"],"parameters":[{"schema":{"type":"string","description":"R2 object key (may contain path separators)"},"required":true,"description":"R2 object key (may contain path separators)","name":"key","in":"path"}],"responses":{"200":{"description":"File content with appropriate Content-Type header"},"304":{"description":"Not Modified (ETag match)"},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/onboarding":{"get":{"summary":"Get onboarding status","description":"Returns onboarding steps with completion status for the authenticated user.","tags":["Onboarding"],"security":[{"BearerToken":["user"]}],"responses":{"200":{"description":"Onboarding steps","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OnboardingStep"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/onboarding/{stepKey}/dismiss":{"post":{"summary":"Dismiss an onboarding step","description":"Marks a specific onboarding step as dismissed for the authenticated user.","tags":["Onboarding"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"stepKey","in":"path"}],"responses":{"200":{"description":"Dismissed onboarding step","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OnboardingStep"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Step not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}},"required":["error","code"]}}}}}}},"/v1/me/onboarding/dismiss-all":{"post":{"summary":"Dismiss all onboarding steps","description":"Marks all onboarding steps as dismissed for the authenticated user.","tags":["Onboarding"],"security":[{"BearerToken":["user"]}],"responses":{"200":{"description":"All steps dismissed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/mcp":{"post":{"summary":"MCP JSON-RPC endpoint","description":"Model Context Protocol (MCP) endpoint using Streamable HTTP transport (spec version `2025-03-26`). Accepts JSON-RPC 2.0 requests for MCP protocol methods. Supports batch requests (up to 10). Notifications (requests without `id`) return 204 No Content.\n\n**Supported methods:**\n- `initialize` — Capability negotiation and protocol version exchange\n- `tools/list` — List available tools (filtered by token scopes)\n- `tools/call` — Execute a tool with validated arguments\n- `resources/list` — List available resources\n- `resources/read` — Read a resource by URI\n- `resources/templates/list` — List URI templates for parameterized resources\n- `prompts/list` — List available prompt templates\n- `prompts/get` — Get a prompt template with arguments\n- `ping` — Health check\n\n**Headers:** Include `Mcp-Session-Id` to maintain session context (echoed back in response).","tags":["MCP"],"security":[{"BearerToken":[]}],"responses":{"200":{"description":"JSON-RPC 2.0 response (single `JsonRpcResponse` object or batch array). Per JSON-RPC 2.0, errors also return 200 with an `error` field.","content":{"application/json":{"schema":{"description":"JSON-RPC 2.0 response — see JsonRpcResponse schema"}}}},"204":{"description":"No Content — notification processed (no response body)"},"400":{"description":"Bad Request — invalid Content-Type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpError"}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpError"}}}}}},"get":{"summary":"MCP SSE endpoint (not supported)","description":"Server-Sent Events endpoint for server-initiated messages. Not implemented — use `POST /mcp` for all MCP communication.","tags":["MCP"],"responses":{"400":{"description":"Bad Request — SSE not supported","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpError"}}}}}},"delete":{"summary":"MCP session termination","description":"Terminates an MCP session. Sessions are stateless on the server side, so this is a no-op that always returns 204.","tags":["MCP"],"security":[{"BearerToken":[]}],"responses":{"204":{"description":"No Content — session terminated"}}}},"/v1/public/groups/{slug}":{"get":{"summary":"Get group by slug","description":"Returns public information about a group including its upcoming events. No authentication required.","tags":["Public"],"security":[],"parameters":[{"schema":{"type":"string","description":"Group URL slug (e.g. \"tampadevs\")"},"required":true,"description":"Group URL slug (e.g. \"tampadevs\")","name":"slug","in":"path"}],"responses":{"200":{"description":"Group details with upcoming events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupDetail"}},"required":["data"]}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/public/groups/{slug}/next-event":{"get":{"summary":"Get next event for a group","description":"Returns the next upcoming event for a group, or 404 if there are no upcoming events. No authentication required.","tags":["Public"],"security":[],"parameters":[{"schema":{"type":"string","description":"Group URL slug (e.g. \"tampadevs\")"},"required":true,"description":"Group URL slug (e.g. \"tampadevs\")","name":"slug","in":"path"}],"responses":{"200":{"description":"Next upcoming event","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EventDetail"}},"required":["data"]}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me":{"get":{"summary":"Get current user identity","description":"Returns basic identity information for the authenticated user. Email is included only if the `user:email` scope is granted.","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"Current user identity","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserBasic"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile":{"get":{"summary":"Get current user profile","description":"Returns the full profile for the authenticated user including bio, social links, and settings.","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"Full user profile","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserProfile"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"summary":"Update current user profile","description":"Updates the authenticated user's profile fields. Only provided fields are updated.","tags":["User"],"security":[{"BearerToken":["user"]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileRequest"}}}},"responses":{"200":{"description":"Updated user profile","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserProfile"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete current user account and all data","tags":["User"],"security":[{"BearerToken":["user"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"confirm":{"type":"string","enum":["DELETE"]}},"required":["confirm"]}}}},"responses":{"200":{"description":"Account deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"400":{"description":"Bad Request — confirmation required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}},"required":["error","code"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/linked-accounts":{"get":{"summary":"List linked OAuth accounts","description":"Returns the OAuth providers (GitHub, Discord, etc.) connected to the authenticated user's account.","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"Linked OAuth accounts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LinkedAccount"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/check-username/{username}":{"get":{"summary":"Check username availability","tags":["User"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"username","in":"path"}],"responses":{"200":{"description":"Username availability","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UsernameCheck"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/primary-email":{"patch":{"summary":"Change primary email","description":"Changes the authenticated user's primary email to one from a linked OAuth identity. Rate limited to 3 requests per 5 minutes.","tags":["User"],"security":[{"BearerToken":["user"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","description":"OAuth provider name (e.g., \"github\", \"google\")"}},"required":["provider"]}}}},"responses":{"200":{"description":"Primary email updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/linked-accounts/{provider}":{"delete":{"summary":"Unlink an OAuth identity","tags":["User"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"provider","in":"path"}],"responses":{"200":{"description":"Identity unlinked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"400":{"description":"Bad Request — cannot unlink last sign-in method","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}},"required":["error","code"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/grants":{"get":{"summary":"List OAuth grants for the current user","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"List of OAuth grants","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OAuthGrant"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/grants/{grantId}":{"delete":{"summary":"Revoke an OAuth grant","tags":["User"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"grantId","in":"path"}],"responses":{"200":{"description":"Grant revoked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/portfolio":{"get":{"summary":"List portfolio items","description":"Returns all portfolio items for the authenticated user, ordered by sort order.","tags":["User"],"security":[{"BearerToken":["read:portfolio"]}],"responses":{"200":{"description":"Portfolio items","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioItem"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create portfolio item","description":"Adds a new portfolio item to the authenticated user's profile.","tags":["User"],"security":[{"BearerToken":["write:portfolio"]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioItemRequest"}}}},"responses":{"201":{"description":"Created portfolio item","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortfolioItem"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/portfolio/{id}":{"patch":{"summary":"Update portfolio item","description":"Updates an existing portfolio item. Only provided fields are changed.","tags":["User"],"security":[{"BearerToken":["write:portfolio"]}],"parameters":[{"schema":{"type":"string","description":"Portfolio item ID"},"required":true,"description":"Portfolio item ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioItemUpdateRequest"}}}},"responses":{"200":{"description":"Updated portfolio item","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortfolioItem"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete portfolio item","description":"Permanently removes a portfolio item from the authenticated user's profile.","tags":["User"],"security":[{"BearerToken":["write:portfolio"]}],"parameters":[{"schema":{"type":"string","description":"Portfolio item ID"},"required":true,"description":"Portfolio item ID","name":"id","in":"path"}],"responses":{"204":{"description":"Portfolio item deleted"},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/achievements":{"get":{"summary":"Get achievement progress","description":"Returns all achievements with the authenticated user's progress toward each.","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"Achievement progress","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AchievementProgress"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/badges":{"get":{"summary":"Get earned badges","description":"Returns all badges earned by the authenticated user, with rarity information.","tags":["User"],"security":[{"BearerToken":["read:user"]}],"responses":{"200":{"description":"User badges","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserBadge"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/entitlements":{"get":{"summary":"Get active entitlements","description":"Returns active entitlements for the authenticated user. Expired entitlements are filtered out. Use `prefix` to check for entitlements under a namespace (e.g., `?prefix=dev.tampa.group`).","tags":["User"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","maxLength":200,"description":"Filter entitlements by key prefix (e.g., \"dev.tampa.group\")","example":"dev.tampa.group"},"required":false,"description":"Filter entitlements by key prefix (e.g., \"dev.tampa.group\")","name":"prefix","in":"query"}],"responses":{"200":{"description":"User entitlements","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UserEntitlement"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/tokens":{"get":{"summary":"List personal access tokens","description":"Returns all personal access tokens for the authenticated user. Token values are not included.","tags":["User"],"security":[{"BearerToken":["user"]}],"responses":{"200":{"description":"Personal access tokens","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Token"}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create personal access token","description":"Creates a new personal access token. The full token value is returned only once in the response -- store it securely.","tags":["User"],"security":[{"BearerToken":["user"]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenRequest"}}}},"responses":{"201":{"description":"Created token with full value","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TokenCreated"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/tokens/{id}":{"delete":{"summary":"Revoke personal access token","description":"Permanently revokes a personal access token. The token can no longer be used for authentication.","tags":["User"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string","description":"Token ID"},"required":true,"description":"Token ID","name":"id","in":"path"}],"responses":{"204":{"description":"Token revoked"},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/feed-token":{"get":{"summary":"Get personal feed token","description":"Returns the user's personal feed token, generating one if it doesn't exist. Use this token to construct personalized RSS/iCal feed URLs at /feed/rss/{token} and /feed/ical/{token}.","tags":["User"],"security":[{"BearerToken":["user"]}],"responses":{"200":{"description":"Personal feed token","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FeedToken"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/profile/feed-token/regenerate":{"post":{"summary":"Regenerate personal feed token","description":"Generates a new feed token, invalidating the previous one. Any existing feed URLs using the old token will stop working.","tags":["User"],"security":[{"BearerToken":["user"]}],"responses":{"200":{"description":"New personal feed token","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FeedToken"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/events":{"get":{"summary":"List upcoming events","description":"Returns a paginated list of upcoming events across all groups, ordered by start time. Supports filtering by group tags, venue city, time window, and favorites.","tags":["Events"],"security":[{"BearerToken":["read:events"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Comma-separated group URL slugs to filter by","example":"react-tampa,ai-tampa"},"required":false,"description":"Comma-separated group URL slugs to filter by","name":"groups","in":"query"},{"schema":{"type":"string","description":"Comma-separated group tags to filter by (OR logic)","example":"ai,ml"},"required":false,"description":"Comma-separated group tags to filter by (OR logic)","name":"tags","in":"query"},{"schema":{"type":"string","description":"Comma-separated venue cities to filter by (OR logic)","example":"Tampa,St. Petersburg"},"required":false,"description":"Comma-separated venue cities to filter by (OR logic)","name":"city","in":"query"},{"schema":{"type":"string","description":"Set to \"1\" to exclude online-only events","example":"1"},"required":false,"description":"Set to \"1\" to exclude online-only events","name":"noonline","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"Only events starting within this many days","example":30},"required":false,"description":"Only events starting within this many days","name":"within_days","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"Only events starting within this many hours"},"required":false,"description":"Only events starting within this many hours","name":"within_hours","in":"query"},{"schema":{"type":"string","description":"Set to \"1\" to return only events from favorited groups (requires read:favorites scope)"},"required":false,"description":"Set to \"1\" to return only events from favorited groups (requires read:favorites scope)","name":"favorites","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of fields to return (sparse field selection)","example":"title,dateTime,group"},"required":false,"description":"Comma-separated list of fields to return (sparse field selection)","name":"fields","in":"query"}],"responses":{"200":{"description":"Upcoming events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EventListItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/events/next":{"get":{"summary":"Get next event per group","description":"Returns one upcoming event for each group (the soonest event). Useful for overview pages. Supports the same filters as GET /events.","tags":["Events"],"security":[{"BearerToken":["read:events"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Comma-separated group URL slugs to filter by","example":"react-tampa,ai-tampa"},"required":false,"description":"Comma-separated group URL slugs to filter by","name":"groups","in":"query"},{"schema":{"type":"string","description":"Comma-separated group tags to filter by (OR logic)","example":"ai,ml"},"required":false,"description":"Comma-separated group tags to filter by (OR logic)","name":"tags","in":"query"},{"schema":{"type":"string","description":"Comma-separated venue cities to filter by (OR logic)","example":"Tampa,St. Petersburg"},"required":false,"description":"Comma-separated venue cities to filter by (OR logic)","name":"city","in":"query"},{"schema":{"type":"string","description":"Set to \"1\" to exclude online-only events","example":"1"},"required":false,"description":"Set to \"1\" to exclude online-only events","name":"noonline","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"Only events starting within this many days","example":30},"required":false,"description":"Only events starting within this many days","name":"within_days","in":"query"},{"schema":{"type":"integer","minimum":1,"description":"Only events starting within this many hours"},"required":false,"description":"Only events starting within this many hours","name":"within_hours","in":"query"},{"schema":{"type":"string","description":"Set to \"1\" to return only events from favorited groups (requires read:favorites scope)"},"required":false,"description":"Set to \"1\" to return only events from favorited groups (requires read:favorites scope)","name":"favorites","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of fields to return (sparse field selection)","example":"title,dateTime,group"},"required":false,"description":"Comma-separated list of fields to return (sparse field selection)","name":"fields","in":"query"}],"responses":{"200":{"description":"Next event per group","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EventListItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/events/{eventId}":{"get":{"summary":"Get event details","description":"Returns a single event by its unique ID, including venue information.","tags":["Events"],"security":[{"BearerToken":["read:events"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"eventId","in":"path"}],"responses":{"200":{"description":"Event details","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EventDetail"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Event not found"}}}},"/v1/events/{eventId}/rsvp":{"get":{"summary":"Get RSVP status","description":"Returns the authenticated user's RSVP status for the specified event.","tags":["Events"],"security":[{"BearerToken":["read:events"]}],"parameters":[{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"RSVP status (null if not RSVPed)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RsvpStatusResponse"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"RSVP to event","description":"Creates an RSVP for the authenticated user. If the event is at capacity, the user is placed on the waitlist.","tags":["Events"],"security":[{"BearerToken":["write:events"]}],"parameters":[{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"201":{"description":"RSVP created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Rsvp"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Cancel RSVP","description":"Cancels the authenticated user's RSVP. If a waitlisted user exists, they are automatically promoted.","tags":["Events"],"security":[{"BearerToken":["write:events"]}],"parameters":[{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"RSVP cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/events/{eventId}/rsvp-summary":{"get":{"summary":"Get RSVP summary","description":"Returns aggregate RSVP counts (confirmed, waitlisted, cancelled) for the specified event.","tags":["Events"],"security":[{"BearerToken":["read:events"]}],"parameters":[{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"RSVP summary counts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RsvpSummary"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/checkin/{code}":{"get":{"summary":"Get checkin code info","description":"Returns event and group info for a checkin code. No authentication required. Used to render the checkin page.","tags":["Events"],"parameters":[{"schema":{"type":"string","description":"Check-in code"},"required":true,"description":"Check-in code","name":"code","in":"path"}],"responses":{"200":{"description":"Checkin code info","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CheckinInfo"}},"required":["data"]}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Check in to event","description":"Self check-in using a check-in code. Optionally specify the check-in method (link, qr, nfc).","tags":["Events"],"security":[{"BearerToken":["write:events"]}],"parameters":[{"schema":{"type":"string","description":"Check-in code"},"required":true,"description":"Check-in code","name":"code","in":"path"}],"responses":{"201":{"description":"Check-in recorded","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CheckinResult"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups":{"get":{"summary":"List groups","description":"Returns a paginated list of groups displayed on the site, ordered by member count. Use ?featured=1 to return only featured groups.","tags":["Groups"],"security":[{"BearerToken":["read:groups"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":["number","null"],"description":"Set to 1 to return only featured groups","example":1},"required":false,"description":"Set to 1 to return only featured groups","name":"featured","in":"query"}],"responses":{"200":{"description":"Groups","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GroupListItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups/{slug}":{"get":{"summary":"Get group details","description":"Returns detailed information about a group including its upcoming events.","tags":["Groups"],"security":[{"BearerToken":["read:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group URL slug (urlname)"},"required":true,"description":"Group URL slug (urlname)","name":"slug","in":"path"}],"responses":{"200":{"description":"Group details with upcoming events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupDetail"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups/{slug}/members":{"get":{"summary":"List group members","description":"Returns a paginated list of public-profile users who have favorited this group.","tags":["Groups"],"security":[{"BearerToken":["read:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group URL slug (urlname)"},"required":true,"description":"Group URL slug (urlname)","name":"slug","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Group members","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GroupMember"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/favorites":{"get":{"summary":"List favorite groups","description":"Returns the groups the authenticated user has favorited.","tags":["Groups"],"security":[{"BearerToken":["read:favorites"]}],"responses":{"200":{"description":"Favorite groups","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/favorites/{groupSlug}":{"post":{"summary":"Add group to favorites","description":"Adds a group to the authenticated user's favorites. Returns 200 if already favorited.","tags":["Groups"],"security":[{"BearerToken":["write:favorites"]}],"parameters":[{"schema":{"type":"string","description":"Group URL slug"},"required":true,"description":"Group URL slug","name":"groupSlug","in":"path"}],"responses":{"200":{"description":"Already favorited","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"alreadyFavorited":{"type":"boolean"}},"required":["alreadyFavorited"]}},"required":["data"]}}}},"201":{"description":"Group added to favorites","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"groupSlug":{"type":"string"}},"required":["groupSlug"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Remove group from favorites","description":"Removes a group from the authenticated user's favorites.","tags":["Groups"],"security":[{"BearerToken":["write:favorites"]}],"parameters":[{"schema":{"type":"string","description":"Group URL slug"},"required":true,"description":"Group URL slug","name":"groupSlug","in":"path"}],"responses":{"204":{"description":"Favorite removed"},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/favorites/sync":{"post":{"summary":"Sync favorites","description":"Merges client-side favorites with server favorites. Adds any slugs not already favorited and returns the combined list.","tags":["Groups"],"security":[{"BearerToken":["write:favorites"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"slugs":{"type":"array","items":{"type":"string"},"maxItems":100}},"required":["slugs"]}}}},"responses":{"200":{"description":"Synced favorites","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"favorites":{"type":"array","items":{"type":"object","properties":{"groupSlug":{"type":"string"}},"required":["groupSlug"]}},"added":{"type":"number"}},"required":["favorites","added"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}/follow":{"post":{"summary":"Follow user","description":"Follows the specified user. Returns 200 if already following.","tags":["Follows"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"}],"responses":{"200":{"description":"Already following","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"alreadyFollowing":{"type":"boolean","enum":[true]}},"required":["alreadyFollowing"]}},"required":["data"]}}}},"201":{"description":"Now following user","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"following":{"type":"boolean","enum":[true]}},"required":["following"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Unfollow user","description":"Unfollows the specified user.","tags":["Follows"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"}],"responses":{"204":{"description":"Unfollowed"},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/me/following/{username}":{"get":{"summary":"Check follow status","description":"Returns whether the authenticated user follows the specified user.","tags":["Follows"],"security":[{"BearerToken":["user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"}],"responses":{"200":{"description":"Follow status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"following":{"type":"boolean"}},"required":["following"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}/followers":{"get":{"summary":"List followers","description":"Returns a paginated list of users following the specified user.","tags":["Follows"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Followers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FollowEntry"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}/following":{"get":{"summary":"List following","description":"Returns a paginated list of users the specified user is following.","tags":["Follows"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Following","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FollowEntry"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}/connections":{"get":{"summary":"List MeetPass connections","description":"Returns a paginated list of people who connected with the specified user via MeetPass. Only available if the user has showMeetpassConnections enabled.","tags":["Follows"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Target username"},"required":true,"description":"Target username","name":"username","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Connections","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectionEntry"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/badges":{"get":{"summary":"List platform badges","description":"Returns all platform badges (not group-scoped) visible in the badge directory, with rarity information.","tags":["Badges"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Platform badges","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BadgeCatalog"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/badges/{slug}":{"get":{"summary":"Get badge detail","description":"Returns detailed information about a single badge by slug, including rarity.","tags":["Badges"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Badge slug"},"required":true,"description":"Badge slug","name":"slug","in":"path"}],"responses":{"200":{"description":"Badge detail","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BadgeDetail"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users":{"get":{"summary":"User directory","description":"Returns a paginated list of public users with their platform badges. Supports search by name/username and filtering by badge slug(s).","tags":["Users"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Search by name or username"},"required":false,"description":"Search by name or username","name":"search","in":"query"},{"schema":{"type":"string","description":"Filter by badge slug(s), comma-separated. User must have ALL listed badges."},"required":false,"description":"Filter by badge slug(s), comma-separated. User must have ALL listed badges.","name":"badge","in":"query"}],"responses":{"200":{"description":"Public users","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PublicUserList"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}":{"get":{"summary":"Get public user profile","description":"Returns a public user profile with badges, achievements, portfolio, favorites, and connections.","tags":["Users"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Username (case-insensitive)"},"required":true,"description":"Username (case-insensitive)","name":"username","in":"path"}],"responses":{"200":{"description":"Public user profile","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PublicUserProfile"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/id/{id}":{"get":{"summary":"Get public user profile by ID","description":"Returns a public user profile by UUID. Useful for stable references when usernames may change.","tags":["Users"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"User UUID"},"required":true,"description":"User UUID","name":"id","in":"path"}],"responses":{"200":{"description":"Public user profile","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PublicUserProfile"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/users/{username}/group-badges":{"get":{"summary":"Get user's group badges","description":"Returns all group-scoped badges for a user, grouped by group with XP subtotals.","tags":["Users"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Username (case-insensitive)"},"required":true,"description":"Username (case-insensitive)","name":"username","in":"path"}],"responses":{"200":{"description":"User's group badges","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/UserGroupBadges"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/leaderboard":{"get":{"summary":"Global XP leaderboard","description":"Returns users ranked by XP score (sum of platform badge points). Only includes public users who have opted in to showing achievements.","tags":["Leaderboard"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Global leaderboard","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GlobalLeaderboard"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups/{slug}/leaderboard":{"get":{"summary":"Group XP leaderboard","description":"Returns users ranked by XP score for badges scoped to a specific group. Only includes public users with a username.","tags":["Leaderboard"],"security":[{"BearerToken":["read:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group URL slug"},"required":true,"description":"Group URL slug","name":"slug","in":"path"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"}],"responses":{"200":{"description":"Group leaderboard","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupLeaderboard"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/leaderboard/movers":{"get":{"summary":"Leaderboard movers","description":"Returns users ranked by XP gained over a time period, plus rank change. High engagement value for showcasing active community members.","tags":["Leaderboard"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","enum":["24h","7d","28d"],"default":"7d","description":"Time window for XP gains"},"required":false,"description":"Time window for XP gains","name":"period","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":100,"default":10,"description":"Maximum number of results (1-100)"},"required":false,"description":"Maximum number of results (1-100)","name":"limit","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Pagination offset"},"required":false,"description":"Pagination offset","name":"offset","in":"query"}],"responses":{"200":{"description":"Leaderboard movers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LeaderboardMovers"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups/claim/{token}":{"get":{"summary":"Look up a group claim invite","tags":["Claims"],"security":[{"BearerToken":["read:groups"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"token","in":"path"}],"responses":{"200":{"description":"Claim invite details","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupClaimInvite"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Accept a group claim invite","tags":["Claims"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"token","in":"path"}],"responses":{"200":{"description":"Claim result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupClaimResult"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/groups/{slug}/claim":{"post":{"summary":"Submit a group claim request without an invite","tags":["Claims"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"slug","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"notes":{"type":"string","maxLength":2000}}}}}},"responses":{"201":{"description":"Claim request submitted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GroupClaimResult"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/claim/{code}":{"get":{"summary":"Get badge claim info","description":"Returns information about a badge claim link. No authentication required.","tags":["Claims"],"security":[],"parameters":[{"schema":{"type":"string","description":"Claim code"},"required":true,"description":"Claim code","name":"code","in":"path"}],"responses":{"200":{"description":"Claim link information","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ClaimInfo"}},"required":["data"]}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Claim a badge","description":"Claims a badge using a claim link code. Requires authentication.","tags":["Claims"],"security":[{"BearerToken":["read:user"]}],"parameters":[{"schema":{"type":"string","description":"Claim code"},"required":true,"description":"Claim code","name":"code","in":"path"}],"responses":{"201":{"description":"Badge claimed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ClaimBadgeResponse"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Gone — resource expired or exhausted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/scopes":{"get":{"summary":"List OAuth scopes","description":"Returns all available OAuth scopes with descriptions and hierarchy. No authentication required.","tags":["Scopes"],"security":[],"responses":{"200":{"description":"Available OAuth scopes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Scope"}}},"required":["data"]}}}}}}},"/v1/meetpass":{"get":{"summary":"List my passes","description":"Returns all MeetPass passes for the authenticated user with connection count.","tags":["MeetPass"],"security":[{"BearerToken":["read:meetpass"]}],"responses":{"200":{"description":"User passes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"passes":{"type":"array","items":{"$ref":"#/components/schemas/Meetpass"}},"totalConnections":{"type":"number"}},"required":["passes","totalConnections"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/meetpass/qr":{"get":{"summary":"Get QR pass","description":"Returns the authenticated user's QR code pass, provisioning one if it does not exist.","tags":["MeetPass"],"security":[{"BearerToken":["read:meetpass"]}],"responses":{"200":{"description":"QR pass with connection count","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/Meetpass"},{"type":"object","properties":{"connectionCount":{"type":"number"}},"required":["connectionCount"]}]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/meetpass/connections":{"get":{"summary":"List connections","description":"Returns a paginated list of MeetPass connections (rolodex) for the authenticated user. Bidirectional: includes both people who tapped your pass (inbound) and people whose pass you tapped (outbound). Default view deduplicates mutual connections; use direction=inbound|outbound to see individual connection events.","tags":["MeetPass"],"security":[{"BearerToken":["read:meetpass"]}],"parameters":[{"schema":{"type":"number","minimum":1,"maximum":100,"default":20,"description":"Maximum number of items to return (1-100)","example":20},"required":false,"description":"Maximum number of items to return (1-100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance."},"required":false,"description":"Opaque cursor for forward pagination. Pass the `nextCursor` value from a previous response to fetch the next page. Recommended over offset for performance.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page."},"required":false,"description":"Opaque cursor for backward pagination. Pass the `prevCursor` value from a previous response to fetch the previous page.","name":"before","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"default":0,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","deprecated":true},"required":false,"description":"Legacy: number of items to skip. Ignored when cursor is provided. Prefer cursor-based pagination for better performance.","name":"offset","in":"query"},{"schema":{"type":"string","enum":["inbound","outbound"],"description":"Filter by direction: inbound (they scanned you) or outbound (you scanned them). Omit for deduplicated rolodex view."},"required":false,"description":"Filter by direction: inbound (they scanned you) or outbound (you scanned them). Omit for deduplicated rolodex view.","name":"direction","in":"query"},{"schema":{"type":"string","enum":["true","false"],"default":"false","description":"Include anonymous (non-registered) visitors in results. Defaults to false. Only affects inbound and default (deduplicated) views — outbound connections are always authenticated users."},"required":false,"description":"Include anonymous (non-registered) visitors in results. Defaults to false. Only affects inbound and default (deduplicated) views — outbound connections are always authenticated users.","name":"includeAnonymous","in":"query"}],"responses":{"200":{"description":"Paginated connections","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MeetpassConnection"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["data","pagination"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/meetpass/{id}":{"get":{"summary":"Get pass details","description":"Returns details for a specific MeetPass pass owned by the authenticated user.","tags":["MeetPass"],"security":[{"BearerToken":["read:meetpass"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Pass details with design and connection count","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/Meetpass"},{"type":"object","properties":{"design":{},"connectionCount":{"type":"number"}},"required":["connectionCount"]}]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"summary":"Update pass","description":"Updates settings on a MeetPass pass owned by the authenticated user.","tags":["MeetPass"],"security":[{"BearerToken":["write:meetpass"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","maxLength":100},"action":{"type":"string","maxLength":500},"autoFollow":{"anyOf":[{"type":"boolean"},{"type":"integer","minimum":0,"maximum":1}]}}}}}},"responses":{"200":{"description":"Updated pass","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Meetpass"}},"required":["data"]}}}},"400":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Release pass","description":"Releases a MeetPass pass, resetting its owner and settings. QR code passes cannot be released.","tags":["MeetPass"],"security":[{"BearerToken":["write:meetpass"]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Pass released successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"400":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups":{"get":{"summary":"List manageable groups","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"responses":{"200":{"description":"Groups the user can manage","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"groups":{"type":"array","items":{"$ref":"#/components/schemas/ManagedGroup"}}},"required":["groups"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create a native group","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"urlname":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$"},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":5000},"website":{"type":"string","format":"uri"},"tags":{"type":"array","items":{"type":"string"}},"socialLinks":{"type":"object","properties":{"slack":{"type":"string","format":"uri"},"discord":{"type":"string","format":"uri"},"linkedin":{"type":"string","format":"uri"},"twitter":{"type":"string","format":"uri"},"github":{"type":"string","format":"uri"},"meetup":{"type":"string","format":"uri"}}},"photoUrl":{"type":"string","format":"uri"},"themeColor":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"}},"required":["urlname","name"]}}}},"responses":{"201":{"description":"Created group","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}":{"get":{"summary":"Get managed group detail","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"Group detail with permissions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"summary":"Update group settings","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":["string","null"],"maxLength":5000},"urlname":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$"},"website":{"type":["string","null"],"format":"uri"},"tags":{"type":["array","null"],"items":{"type":"string"}},"socialLinks":{"type":["object","null"],"properties":{"slack":{"type":"string","format":"uri"},"discord":{"type":"string","format":"uri"},"linkedin":{"type":"string","format":"uri"},"twitter":{"type":"string","format":"uri"},"github":{"type":"string","format":"uri"},"meetup":{"type":"string","format":"uri"}}},"photoUrl":{"type":["string","null"],"format":"uri"},"heroImageUrl":{"type":["string","null"],"format":"uri"},"themeColor":{"type":["string","null"],"pattern":"^#[0-9A-Fa-f]{6}$"}}}}}},"responses":{"200":{"description":"Updated group","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/role":{"get":{"summary":"Check user role in group","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"User role and permissions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/members":{"get":{"summary":"List group members","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"Group members","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Add a member to group","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"role":{"type":"string","enum":["member","volunteer"],"default":"member"}},"required":["userId"]}}}},"responses":{"201":{"description":"Created member","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/members/{memberId}":{"patch":{"summary":"Update member role","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Member ID"},"required":true,"description":"Member ID","name":"memberId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["owner","manager","volunteer","member"]}},"required":["role"]}}}},"responses":{"200":{"description":"Updated member","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Remove a group member","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Member ID"},"required":true,"description":"Member ID","name":"memberId","in":"path"}],"responses":{"200":{"description":"Member removed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/leave":{"post":{"summary":"Leave a group","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"Left group","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/request-creation":{"post":{"summary":"Submit group creation request","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"groupName":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["groupName"]}}}},"responses":{"201":{"description":"Creation request submitted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/my-creation-requests":{"get":{"summary":"List my group creation requests","tags":["Management"],"security":[{"BearerToken":["manage:groups"]}],"responses":{"200":{"description":"User creation requests","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/events":{"get":{"summary":"List managed group events","tags":["Management"],"security":[{"BearerToken":["manage:events"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"Group events with counts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create a native event","tags":["Management"],"security":[{"BearerToken":["manage:events"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":10000},"startTime":{"type":"string"},"endTime":{"type":"string"},"timezone":{"type":"string","default":"America/New_York"},"eventType":{"type":"string","enum":["physical","online","hybrid"],"default":"physical"},"maxAttendees":{"type":"integer","exclusiveMinimum":0},"venue":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"address":{"type":"string","maxLength":500},"city":{"type":"string","maxLength":100},"state":{"type":"string","maxLength":100},"postalCode":{"type":"string","maxLength":20},"country":{"type":"string","maxLength":100},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["name"]},"photoUrl":{"type":"string","format":"uri"},"status":{"type":"string","enum":["active","draft"],"default":"active"}},"required":["title","startTime"]}}}},"responses":{"201":{"description":"Created event with checkin code","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/events/{eventId}":{"get":{"summary":"Get managed event detail","tags":["Management"],"security":[{"BearerToken":["manage:events"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"Event detail with venue, RSVP summary, and checkin codes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"summary":"Update a native event","tags":["Management"],"security":[{"BearerToken":["manage:events"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":["string","null"],"maxLength":10000},"startTime":{"type":"string"},"endTime":{"type":["string","null"]},"timezone":{"type":"string"},"eventType":{"type":"string","enum":["physical","online","hybrid"]},"maxAttendees":{"type":["integer","null"],"exclusiveMinimum":0},"venue":{"type":["object","null"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"address":{"type":"string","maxLength":500},"city":{"type":"string","maxLength":100},"state":{"type":"string","maxLength":100},"postalCode":{"type":"string","maxLength":20},"country":{"type":"string","maxLength":100},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["name"]},"photoUrl":{"type":["string","null"],"format":"uri"},"status":{"type":"string","enum":["active","draft"]}}}}}},"responses":{"200":{"description":"Updated event","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/events/{eventId}/cancel":{"post":{"summary":"Cancel a native event","tags":["Management"],"security":[{"BearerToken":["manage:events"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"Event cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/badges":{"get":{"summary":"List group badges","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"responses":{"200":{"description":"Group badges with counts and limits","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create a group badge","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"slug":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$"},"description":{"type":["string","null"],"maxLength":500},"icon":{"type":"string","minLength":1,"maxLength":20},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","default":"#E5574F"},"points":{"type":"integer","minimum":0},"sortOrder":{"type":"integer","minimum":0,"default":0}},"required":["name","slug","icon","points"]}}}},"responses":{"201":{"description":"Created badge","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ManagedBadge"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/badges/{badgeId}":{"patch":{"summary":"Update a group badge","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":500},"icon":{"type":"string","minLength":1,"maxLength":20},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"points":{"type":"integer","minimum":0},"sortOrder":{"type":"integer","minimum":0}}}}}},"responses":{"200":{"description":"Updated badge","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ManagedBadge"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete a group badge","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"}],"responses":{"200":{"description":"Badge deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/badges/{badgeId}/award/{userId}":{"post":{"summary":"Award badge to user","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"},{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"userId","in":"path"}],"responses":{"201":{"description":"Badge awarded","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"awarded":{"type":"boolean"}},"required":["awarded"]}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict — duplicate or state conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/badges/{badgeId}/revoke/{userId}":{"delete":{"summary":"Revoke badge from user","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"},{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"userId","in":"path"}],"responses":{"200":{"description":"Badge revoked","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/badges/{badgeId}/claim-links":{"post":{"summary":"Create badge claim link","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"maxUses":{"type":["integer","null"],"minimum":1},"expiresAt":{"type":["string","null"]}},"default":{}}}}},"responses":{"201":{"description":"Created claim link","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ClaimLink"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"summary":"List badge claim links","tags":["Management"],"security":[{"BearerToken":["manage:badges"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Badge ID"},"required":true,"description":"Badge ID","name":"badgeId","in":"path"}],"responses":{"200":{"description":"Badge claim links","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/events/{eventId}/checkin-codes":{"post":{"summary":"Create checkin code","tags":["Management"],"security":[{"BearerToken":["manage:checkins"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"maxUses":{"type":["integer","null"],"minimum":1},"expiresAt":{"type":["string","null"]}},"default":{}}}}},"responses":{"201":{"description":"Created checkin code","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CheckinCode"}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"summary":"List checkin codes","tags":["Management"],"security":[{"BearerToken":["manage:checkins"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"Checkin codes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/checkin-codes/{codeId}":{"delete":{"summary":"Delete a checkin code","tags":["Management"],"security":[{"BearerToken":["manage:checkins"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Checkin code ID"},"required":true,"description":"Checkin code ID","name":"codeId","in":"path"}],"responses":{"200":{"description":"Checkin code deleted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]}},"required":["success"],"additionalProperties":{}}},"required":["data"]}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/manage/groups/{groupId}/events/{eventId}/attendees":{"get":{"summary":"List event attendees","tags":["Management"],"security":[{"BearerToken":["manage:checkins"]}],"parameters":[{"schema":{"type":"string","description":"Group ID"},"required":true,"description":"Group ID","name":"groupId","in":"path"},{"schema":{"type":"string","description":"Event ID"},"required":true,"description":"Event ID","name":"eventId","in":"path"}],"responses":{"200":{"description":"Event attendees with RSVP and checkin status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"401":{"description":"Unauthorized — missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden — insufficient scope or permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found — resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}