{"openapi":"3.0.0","info":{"title":"GoBearCats OS Public API","version":"3.0.0","description":"Public REST API for UC Bearcats Athletic Department integrations.\n\nAll endpoints (except `/health` and `/openapi.json`) require an `x-api-key` header.\n\n## Authentication\nInclude your API key in every request:\n```\nx-api-key: sk_live_abc123...\n```\n\n## Pagination\nList endpoints support `?limit=` and `?offset=` query parameters. Responses include a `meta` object with `count`, `limit`, and `offset`.\n\n## Rate Limiting\nEach API key has a per-minute rate limit. Responses include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers.\n\n## Error Codes\nAll errors include a `code` field: `INVALID_PARAMS`, `MISSING_FIELDS`, `NOT_FOUND`, `SCOPE_DENIED`, `RATE_LIMIT_EXCEEDED`, `KEY_EXPIRED`, `AUTH_REQUIRED`.\n\n## Batch Requests\n`POST /batch` accepts up to 10 sub-requests in a single call.\n\n## Request ID\nEvery response includes an `X-Request-Id` header for debugging.","contact":{"name":"UC Athletics Digital Strategy","url":"https://gobearcats.com"}},"servers":[{"url":"https://uoajdcjyjbkjrdcphetx.supabase.co/functions/v1/api-gateway","description":"Production"}],"tags":[{"name":"System","description":"Health checks, metadata, and batch operations"},{"name":"Coffee with Cunningham","description":"CWC events, registrations, and aggregate stats"},{"name":"Events","description":"Published events, registrations, and check-ins"},{"name":"Staff","description":"Staff directory with positions, sports, bios, and social links"},{"name":"Schedule","description":"Cached schedules and game results from ingested data"},{"name":"Stats","description":"Aggregate win/loss statistics by sport and season"},{"name":"Announcements","description":"Published internal announcements"},{"name":"Surveys","description":"Survey metrics (aggregated, no PII)"},{"name":"Buildings","description":"Campus buildings and rooms"},{"name":"Resources","description":"Resource library files and documents"},{"name":"Directory","description":"Public-facing staff directory and update requests"},{"name":"Donors","description":"Customer propensity data and lapsed donor lists"},{"name":"Display","description":"Manual display items for ScreenCloud and digital signage"},{"name":"Game Promotions","description":"Active game-day promotions and sponsorships"},{"name":"Calendar","description":"Public calendar events"},{"name":"ESPN Promos","description":"ESPN+ promotional campaigns and spin-the-wheel"},{"name":"Churn","description":"At-risk customer alerts and scan history"},{"name":"Notes","description":"Note cards for staff recognition"},{"name":"Rooms","description":"Room inventory and space allocations"},{"name":"Budgets","description":"Budget allocations and ledger entries"},{"name":"Events Master","description":"Unified events calendar from all sources"},{"name":"DAM","description":"Digital asset management — assets and brand portals"},{"name":"Appointments","description":"Unpaid appointment/volunteer statistics"},{"name":"OneTeam","description":"OneTeam committee members"},{"name":"Newsletters","description":"Published newsletter history"},{"name":"Admin","description":"Key management (requires admin JWT)"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key issued via the admin panel"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Admin JWT for key management"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"data":{"description":"Response payload"},"meta":{"$ref":"#/components/schemas/Meta"}}},"Meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"ErrorResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"error":{"type":"string"},"code":{"type":"string","example":"NOT_FOUND"}}},"CwcEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"event_date":{"type":"string","format":"date"},"special_guest":{"type":"string","nullable":true},"guest_bio":{"type":"string","nullable":true},"status":{"type":"string","enum":["scheduled","completed","cancelled"]},"registered_count":{"type":"integer"},"attended_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"slug":{"type":"string"},"event_date":{"type":"string","format":"date"},"start_time":{"type":"string","nullable":true},"end_time":{"type":"string","nullable":true},"location":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"max_capacity":{"type":"integer","nullable":true},"cover_image_url":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"},"nullable":true}}},"StaffMember":{"type":"object","properties":{"ucid":{"type":"string"},"name":{"type":"string"},"title":{"type":"string","nullable":true},"department":{"type":"string","nullable":true},"sport":{"type":"string","nullable":true},"functional_area":{"type":"string","nullable":true},"photo_url":{"type":"string","nullable":true}}},"StaffDetail":{"type":"object","allOf":[{"$ref":"#/components/schemas/StaffMember"}],"properties":{"bio":{"type":"string","nullable":true},"hire_date":{"type":"string","format":"date","nullable":true},"social":{"type":"object","properties":{"twitter":{"type":"string","nullable":true},"instagram":{"type":"string","nullable":true},"linkedin":{"type":"string","nullable":true}}}}},"ChurnAlert":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"alert_type":{"type":"string"},"severity":{"type":"string"},"disposition":{"type":"string"},"customer_name":{"type":"string","nullable":true},"revenue_at_risk":{"type":"number","nullable":true},"propensity_score":{"type":"number","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"EspnPromoLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"is_active":{"type":"boolean"},"win_probability":{"type":"number","nullable":true},"og_title":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"NoteCard":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"recipient_name":{"type":"string"},"recipient_type":{"type":"string","nullable":true},"occasion":{"type":"string","nullable":true},"status":{"type":"string"},"submitter_name":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"BudgetAllocation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"department":{"type":"string"},"fiscal_year":{"type":"integer"},"total_budget":{"type":"number"},"created_at":{"type":"string","format":"date-time"}}},"EventsMaster":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"sport":{"type":"string","nullable":true},"source":{"type":"string"},"start_at_utc":{"type":"string","format":"date-time"},"location":{"type":"string","nullable":true},"opponent":{"type":"string","nullable":true},"is_home":{"type":"boolean","nullable":true},"result":{"type":"string","nullable":true}}},"DamAsset":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"file_type":{"type":"string"},"byte_size":{"type":"integer","nullable":true},"keywords":{"type":"array","items":{"type":"string"},"nullable":true},"created_at":{"type":"string","format":"date-time"}}},"DamPortal":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"visibility":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"BatchRequest":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string","default":"GET"},"path":{"type":"string"},"params":{"type":"object"}},"required":["path"]}}}}}},"security":[{"ApiKeyAuth":[]}],"paths":{"/health":{"get":{"summary":"Health check","tags":["System"],"security":[],"responses":{"200":{"description":"API is healthy"}}}},"/openapi.json":{"get":{"summary":"OpenAPI specification","tags":["System"],"security":[],"responses":{"200":{"description":"OpenAPI 3.0 JSON spec"}}}},"/batch":{"post":{"summary":"Batch multiple API calls","tags":["System"],"description":"Execute up to 10 API calls in a single request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}}},"responses":{"200":{"description":"Batch results"},"400":{"description":"Invalid batch request"}}}},"/cwc/events":{"get":{"summary":"List CWC events","tags":["Coffee with Cunningham"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"CWC event list"},"401":{"description":"Invalid key"},"429":{"description":"Rate limited"}}}},"/cwc/events/{id}":{"get":{"summary":"CWC event detail with registrations","tags":["Coffee with Cunningham"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event with registrations"},"404":{"description":"Not found"}}}},"/cwc/events/{id}/register":{"post":{"summary":"Register for CWC event","tags":["Coffee with Cunningham"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["first_name","last_name","email"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"question":{"type":"string"}}}}}},"responses":{"201":{"description":"Registered"},"400":{"description":"Validation error"}}}},"/cwc/stats":{"get":{"summary":"CWC aggregate statistics","tags":["Coffee with Cunningham"],"responses":{"200":{"description":"Stats"}}}},"/events":{"get":{"summary":"List published events","tags":["Events"],"parameters":[{"name":"tag","in":"query","schema":{"type":"string"},"description":"Filter by tag"},{"name":"include_past","in":"query","schema":{"type":"boolean"},"description":"Include past events"},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Event list"}}}},"/events/{id}":{"get":{"summary":"Event detail by UUID or slug","tags":["Events"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Event detail"},"404":{"description":"Not found"}}}},"/events/{id}/registrations":{"get":{"summary":"Event registrations","tags":["Events"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Registration list"}}}},"/events/{id}/register":{"post":{"summary":"Register for event","tags":["Events"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["first_name","last_name","email"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"custom_responses":{"type":"object"}}}}}},"responses":{"201":{"description":"Registered"},"400":{"description":"Error"}}}},"/ga4/report":{"get":{"summary":"GA4 report for a fixed date range (gobearcats.com)","tags":["Analytics"],"parameters":[{"name":"preset","in":"query","required":true,"schema":{"type":"string","enum":["totals","channels","social-sources","social-landing","social-tickets","top-pages","tickets-all","outbound-clicks","platform","daily","cities"]}},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"end","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"section","in":"query","description":"Optional fixed slice: web (website only, no app), football or mens-basketball (that sport's pages)","schema":{"type":"string","enum":["web","football","mens-basketball"]}},{"name":"limit","in":"query","description":"Maximum 50, except cities (5000)","schema":{"type":"integer","default":25,"maximum":5000}}],"responses":{"200":{"description":"Report rows"}}}},"/agency-report/weeks":{"post":{"summary":"Push Agency Report weekly builds (upsert on week_end; in-app inputs kept)","tags":["Analytics"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"One week payload from scripts/sprout-agency-report, or {\"weeks\": [...]} (max 8)"}}}},"responses":{"200":{"description":"Imported week_end dates"},"400":{"description":"Invalid payload"}}}},"/gsc/report":{"get":{"summary":"Search Console search analytics for a fixed date range (gobearcats.com)","tags":["Analytics"],"parameters":[{"name":"preset","in":"query","required":true,"schema":{"type":"string","enum":["totals","queries","pages","devices","sites"]}},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"end","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":50}}],"responses":{"200":{"description":"Report rows"}}}},"/staff":{"get":{"summary":"Staff directory","tags":["Staff"],"parameters":[{"name":"department","in":"query","schema":{"type":"string"}},{"name":"sport","in":"query","schema":{"type":"string"}},{"name":"functional_area","in":"query","schema":{"type":"string"},"description":"Filter by functional area"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Search by name"},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Staff list"}}}},"/staff/{ucid}":{"get":{"summary":"Staff member detail with social links","tags":["Staff"],"parameters":[{"name":"ucid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Staff detail with bio and social links"},"404":{"description":"Not found"}}}},"/schedule":{"get":{"summary":"Cached game schedule","tags":["Schedule"],"parameters":[{"name":"sport","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Cached schedule"}}}},"/schedule/games":{"get":{"summary":"Game results","tags":["Schedule"],"parameters":[{"name":"sport","in":"query","schema":{"type":"string"}},{"name":"season","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}}],"responses":{"200":{"description":"Game results"}}}},"/schedule/upcoming":{"get":{"summary":"Upcoming games","tags":["Schedule"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":10}}],"responses":{"200":{"description":"Upcoming games"}}}},"/stats/department-wins":{"get":{"summary":"Wins/losses by sport and season","tags":["Stats"],"responses":{"200":{"description":"Department wins"}}}},"/announcements":{"get":{"summary":"Published announcements","tags":["Announcements"],"parameters":[{"name":"category","in":"query","schema":{"type":"string"},"description":"Filter by category"},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Announcement list"}}}},"/announcements/{id}":{"get":{"summary":"Announcement detail","tags":["Announcements"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Announcement"},"404":{"description":"Not found"}}}},"/surveys":{"get":{"summary":"Survey list (aggregated)","tags":["Surveys"],"parameters":[{"name":"category","in":"query","schema":{"type":"string"}},{"name":"sport","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Survey list"}}}},"/surveys/{id}":{"get":{"summary":"Survey detail","tags":["Surveys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Survey"},"404":{"description":"Not found"}}}},"/surveys/{id}/summary":{"get":{"summary":"AI survey summary","tags":["Surveys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Summary"},"404":{"description":"Not found"}}}},"/buildings":{"get":{"summary":"List buildings","tags":["Buildings"],"parameters":[{"name":"campus","in":"query","schema":{"type":"string"},"description":"Filter by campus"},{"name":"limit","in":"query","schema":{"type":"integer","default":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Building list"}}}},"/buildings/{id}/rooms":{"get":{"summary":"Building rooms","tags":["Buildings"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Rooms"},"404":{"description":"Building not found"}}}},"/resources":{"get":{"summary":"Resource library","tags":["Resources"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Resources"}}}},"/directory":{"get":{"summary":"Public directory","tags":["Directory"],"parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Directory listing"}}}},"/directory/update-request":{"post":{"summary":"Submit directory update","tags":["Directory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ucid","submitter_name","submitter_email","changes_requested"],"properties":{"ucid":{"type":"string"},"submitter_name":{"type":"string"},"submitter_email":{"type":"string"},"changes_requested":{"type":"object"},"reason":{"type":"string"}}}}}},"responses":{"201":{"description":"Submitted"}}}},"/donors/propensity":{"get":{"summary":"Propensity scores","tags":["Donors"],"parameters":[{"name":"min_score","in":"query","schema":{"type":"number"},"description":"Minimum propensity score"},{"name":"customer_type","in":"query","schema":{"type":"string"},"description":"Filter by type"},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Propensity data"}}}},"/donors/prior-no-current":{"get":{"summary":"Lapsed donors","tags":["Donors"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Lapsed donors"}}}},"/display/items":{"get":{"summary":"Display items","tags":["Display"],"parameters":[{"name":"channel","in":"query","schema":{"type":"string","default":"default"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Display items"}}}},"/display/items/{id}":{"get":{"summary":"Single display item","tags":["Display"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Item"},"404":{"description":"Not found"}}}},"/game-promotions":{"get":{"summary":"Active promotions","tags":["Game Promotions"],"parameters":[{"name":"sport","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Promotions"}}}},"/game-promotions/{id}":{"get":{"summary":"Promotion detail","tags":["Game Promotions"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Promotion"},"404":{"description":"Not found"}}}},"/calendar":{"get":{"summary":"Calendar events","tags":["Calendar"],"parameters":[{"name":"type","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}},{"name":"related_id","in":"query","schema":{"type":"string"},"description":"Filter by linked event"},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Calendar events"}}}},"/calendar/{id}":{"get":{"summary":"Calendar event detail","tags":["Calendar"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event"},"404":{"description":"Not found"}}}},"/espn-promos/links":{"get":{"summary":"Active ESPN+ promo links","tags":["ESPN Promos"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Promo links"}}}},"/espn-promos/links/{slug}":{"get":{"summary":"Promo link by slug","tags":["ESPN Promos"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Promo link"},"404":{"description":"Not found"}}}},"/espn-promos/spin":{"post":{"summary":"Spin the wheel","tags":["ESPN Promos"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["first_name","last_name","email"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"campaign_slug":{"type":"string"},"custom_data":{"type":"object"},"signature_data":{"type":"string"}}}}}},"responses":{"200":{"description":"Lost"},"201":{"description":"Won"},"400":{"description":"Already spun / error"}}}},"/espn-promos/stats":{"get":{"summary":"ESPN promo aggregate stats","tags":["ESPN Promos"],"responses":{"200":{"description":"Stats"}}}},"/churn/alerts":{"get":{"summary":"Churn alerts","tags":["Churn"],"parameters":[{"name":"severity","in":"query","schema":{"type":"string"}},{"name":"disposition","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Alert list"}}}},"/churn/alerts/{id}":{"get":{"summary":"Churn alert detail","tags":["Churn"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Alert"},"404":{"description":"Not found"}}}},"/churn/scan-history":{"get":{"summary":"Churn scan history","tags":["Churn"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Scan history"}}}},"/notes":{"get":{"summary":"List note cards","tags":["Notes"],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"recipient_type","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Notes"}}},"post":{"summary":"Submit a note card","tags":["Notes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["recipient_name","submitter_name","submitter_email"],"properties":{"recipient_name":{"type":"string"},"recipient_type":{"type":"string"},"occasion":{"type":"string"},"message":{"type":"string"},"submitter_name":{"type":"string"},"submitter_email":{"type":"string"}}}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Validation error"}}}},"/notes/{id}":{"get":{"summary":"Note card detail","tags":["Notes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Note"},"404":{"description":"Not found"}}}},"/rooms":{"get":{"summary":"Room inventory","tags":["Rooms"],"parameters":[{"name":"building_code","in":"query","schema":{"type":"string"},"description":"Filter by building code"},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Rooms"}}}},"/rooms/{id}/allocations":{"get":{"summary":"Room allocations","tags":["Rooms"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Allocations"}}}},"/budgets":{"get":{"summary":"Budget allocations","tags":["Budgets"],"parameters":[{"name":"department","in":"query","schema":{"type":"string"}},{"name":"fiscal_year","in":"query","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Budgets"}}}},"/budgets/{id}/ledger":{"get":{"summary":"Ledger entries for budget","tags":["Budgets"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Ledger entries"}}}},"/events-master":{"get":{"summary":"Unified events calendar","tags":["Events Master"],"parameters":[{"name":"sport","in":"query","schema":{"type":"string"}},{"name":"source","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Events"}}}},"/events-master/{id}":{"get":{"summary":"Event detail","tags":["Events Master"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event"},"404":{"description":"Not found"}}}},"/dam/assets":{"get":{"summary":"Digital assets","tags":["DAM"],"parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Assets"}}}},"/dam/portals":{"get":{"summary":"Public brand portals","tags":["DAM"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Portals"}}}},"/dam/portals/{slug}":{"get":{"summary":"Portal detail with kits","tags":["DAM"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Portal with kits"},"404":{"description":"Not found"}}}},"/appointments/stats":{"get":{"summary":"Appointment/volunteer statistics","tags":["Appointments"],"responses":{"200":{"description":"Stats"}}}},"/oneteam/committee":{"get":{"summary":"OneTeam committee members","tags":["OneTeam"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Committee members"}}}},"/newsletters":{"get":{"summary":"Published newsletters","tags":["Newsletters"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Newsletters"}}}},"/keys":{"post":{"summary":"Create API key (admin JWT)","tags":["Admin"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"rate_limit_per_minute":{"type":"integer","default":60},"expires_at":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"Key created"},"401":{"description":"Unauthorized"},"403":{"description":"Admin only"}}}}}}