{"openapi":"3.1.0","info":{"title":"FenceScore API","version":"1.0.0","description":"REST API for the FenceScore fencing tournament platform. Every response is `{ok:true,data}` or `{ok:false,error:{code,message,details?}}`. `:tid` accepts a numeric id or the tournament slug. Webhook deliveries are signed `X-FenceScore-Signature: t=<unix>,v1=<hmac-sha256 of t.body>`."},"servers":[{"url":"https://fencing.lumenaproductions.com/api/v1"}],"tags":[{"name":"Tournaments"},{"name":"Events"},{"name":"Categories"},{"name":"Fencers & entries"},{"name":"Check-in"},{"name":"Forms"},{"name":"Staff"},{"name":"Organizations"},{"name":"Pools"},{"name":"Tableau & results"},{"name":"Strips"},{"name":"Bouts"},{"name":"Broadcast"},{"name":"Tickets"},{"name":"API keys"},{"name":"Webhooks"},{"name":"Meta"}],"paths":{"/orgs":{"get":{"tags":["Organizations"],"summary":"List the caller's organizations","description":"Requires a signed-in user or API key.","operationId":"get_orgs","parameters":[],"x-scopes":["user"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]},"post":{"tags":["Organizations"],"summary":"Create an organization","description":"Requires a signed-in user or API key.","operationId":"post_orgs","parameters":[],"x-scopes":["user"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}}}},"/orgs/{orgId}/members":{"get":{"tags":["Organizations"],"summary":"List organization members","description":"Requires write scope (organizer/staff).","operationId":"get_orgs_orgId_members","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/orgs/{orgId}/invites":{"post":{"tags":["Organizations"],"summary":"Invite someone to an organization; returns an invite link","description":"Requires write scope (organizer/staff).","operationId":"post_orgs_orgId_invites","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"role":{"type":"string","enum":["owner","organizer","staff"]}},"required":["email","role"]}}}}}},"/categories":{"get":{"tags":["Categories"],"summary":"List synced fencing categories","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_categories","parameters":[{"name":"weapon","in":"query","required":false,"schema":{"type":"string"}},{"name":"gender","in":"query","required":false,"schema":{"type":"string"}},{"name":"age_group","in":"query","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"active","in":"query","required":false,"schema":{"type":"boolean"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/categories/{id}":{"get":{"tags":["Categories"],"summary":"Get one category","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_categories_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/categories/sync":{"post":{"tags":["Categories"],"summary":"Run a category sync now (superadmin/admin); returns the run with diff","description":"Requires admin scope / org owner or organizer.","operationId":"post_categories_sync","parameters":[],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]}},"/categories/sync-runs":{"get":{"tags":["Categories"],"summary":"List category sync runs","description":"Requires read access.","operationId":"get_categories_sync_runs","parameters":[],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/tournaments":{"get":{"tags":["Tournaments"],"summary":"List tournaments (public ones for anonymous callers)","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"mine","in":"query","required":false,"schema":{"type":"boolean"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Tournaments"],"summary":"Create a tournament","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments","parameters":[],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"integer"},"name":{"type":"string"},"venue":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"timezone":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"description":{"type":"string"}},"required":["orgId","name"]}}}}}},"/tournaments/{tid}":{"get":{"tags":["Tournaments"],"summary":"Get a tournament with events summary and counts","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"patch":{"tags":["Tournaments"],"summary":"Update a tournament","description":"Requires write scope (organizer/staff).","operationId":"patch_tournaments_tid","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"venue":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"timezone":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"description":{"type":"string"},"status":{"type":"string","enum":["draft","published","live","completed","archived"]}}}}}}},"delete":{"tags":["Tournaments"],"summary":"Delete a tournament (requires confirm=true)","description":"Requires write scope (organizer/staff).","operationId":"delete_tournaments_tid","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/publish":{"post":{"tags":["Tournaments"],"summary":"Publish a tournament","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_publish","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/archive":{"post":{"tags":["Tournaments"],"summary":"Archive a tournament","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_archive","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/events":{"get":{"tags":["Events"],"summary":"List a tournament's events","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_events","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Events"],"summary":"Create an event (name defaults from the category)","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_events","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"categoryId":{"type":"integer"},"name":{"type":"string"},"weapon":{"type":"string","enum":["foil","epee","saber"]},"gender":{"type":"string","enum":["men","women","mixed"]},"ageGroup":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"format":{"type":"string","enum":["pools_de","de_only","pools_only"]},"promotionPct":{"type":"integer"},"poolTouches":{"type":"integer"},"deTouches":{"type":"integer"},"entryFeeCents":{"type":"integer"},"maxEntries":{"type":"integer"}},"required":["weapon","gender"]}}}}}},"/events/{eid}":{"get":{"tags":["Events"],"summary":"Get an event","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"patch":{"tags":["Events"],"summary":"Update an event","description":"Requires write scope (organizer/staff).","operationId":"patch_events_eid","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"categoryId":{"type":"integer"},"name":{"type":"string"},"weapon":{"type":"string","enum":["foil","epee","saber"]},"gender":{"type":"string","enum":["men","women","mixed"]},"ageGroup":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"format":{"type":"string","enum":["pools_de","de_only","pools_only"]},"promotionPct":{"type":"integer"},"poolTouches":{"type":"integer"},"deTouches":{"type":"integer"},"entryFeeCents":{"type":"integer"},"maxEntries":{"type":"integer"}}}}}}},"delete":{"tags":["Events"],"summary":"Delete an event (requires confirm=true)","description":"Requires write scope (organizer/staff).","operationId":"delete_events_eid","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/events/{eid}/status":{"post":{"tags":["Events"],"summary":"Set an event's status","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_status","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","registration_open","registration_closed","checkin","pools","de","completed"]}},"required":["status"]}}}}}},"/fencers":{"get":{"tags":["Fencers & entries"],"summary":"Search fencers","description":"Requires read access.","operationId":"get_fencers","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"club","in":"query","required":false,"schema":{"type":"string"}},{"name":"member","in":"query","required":false,"schema":{"type":"string"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]},"post":{"tags":["Fencers & entries"],"summary":"Create a fencer","description":"Requires write scope (organizer/staff).","operationId":"post_fencers","parameters":[],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"club":{"type":"string"},"division":{"type":"string"},"country":{"type":"string"},"memberNumber":{"type":"string"},"rating":{"type":"string"},"birthYear":{"type":"integer"},"gender":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}},"required":["firstName","lastName"]}}}}}},"/fencers/{fid}":{"get":{"tags":["Fencers & entries"],"summary":"Get a fencer","description":"Requires read access.","operationId":"get_fencers_fid","parameters":[{"name":"fid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]},"patch":{"tags":["Fencers & entries"],"summary":"Update a fencer","description":"Requires write scope (organizer/staff).","operationId":"patch_fencers_fid","parameters":[{"name":"fid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"club":{"type":"string"},"division":{"type":"string"},"country":{"type":"string"},"memberNumber":{"type":"string"},"rating":{"type":"string"},"birthYear":{"type":"integer"},"gender":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}}}}}}}},"/fencers/{fid}/photo":{"post":{"tags":["Fencers & entries"],"summary":"Upload a fencer photo (multipart field 'photo')","description":"Requires write scope (organizer/staff).","operationId":"post_fencers_fid_photo","parameters":[{"name":"fid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"photo":{"type":"string","format":"binary"}},"required":["photo"]}}}}}},"/events/{eid}/entries":{"get":{"tags":["Fencers & entries"],"summary":"List an event's entries with fencer fields, status, seed, check-in and forms-complete flag","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid_entries","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Fencers & entries"],"summary":"Add an entry by fencerId or inline fencer fields","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_entries","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fencerId":{"type":"integer"},"firstName":{"type":"string"},"lastName":{"type":"string"},"club":{"type":"string"},"division":{"type":"string"},"country":{"type":"string"},"memberNumber":{"type":"string"},"rating":{"type":"string"},"birthYear":{"type":"integer"},"gender":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}}}}}}}},"/events/{eid}/entries/import":{"post":{"tags":["Fencers & entries"],"summary":"Import entries from CSV text","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_entries_import","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"csv":{"type":"string"}},"required":["csv"]}}}}}},"/entries/{entryId}":{"patch":{"tags":["Fencers & entries"],"summary":"Update an entry","description":"Requires write scope (organizer/staff).","operationId":"patch_entries_entryId","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["registered","checked_in","scratched","withdrawn","excluded"]},"seed":{"type":"integer"},"paid":{"type":"boolean"},"insuranceVerified":{"type":"boolean"},"membershipVerified":{"type":"boolean"}}}}}}},"delete":{"tags":["Fencers & entries"],"summary":"Withdraw an entry (requires confirm=true)","description":"Requires write scope (organizer/staff).","operationId":"delete_entries_entryId","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/staff":{"get":{"tags":["Staff"],"summary":"List tournament staff","description":"Requires write scope (organizer/staff).","operationId":"get_tournaments_tid_staff","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]},"post":{"tags":["Staff"],"summary":"Grant a role to an existing user or create an invite","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_staff","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"role":{"type":"string","enum":["organizer","staff","scorekeeper","referee","armorer","checkin"]},"stripNumber":{"type":"integer"}},"required":["email","role"]}}}}}},"/tournaments/{tid}/staff/{userId}/{role}":{"delete":{"tags":["Staff"],"summary":"Remove a staff grant","description":"Requires write scope (organizer/staff).","operationId":"delete_tournaments_tid_staff_userId_role","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"userId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"role","in":"path","required":true,"schema":{"type":"string"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/forms":{"get":{"tags":["Forms"],"summary":"List form templates","description":"Requires read access.","operationId":"get_tournaments_tid_forms","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]},"post":{"tags":["Forms"],"summary":"Create a form template","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_forms","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["waiver","insurance","medical","photo_release","custom"]},"title":{"type":"string"},"bodyHtml":{"type":"string"},"required":{"type":"boolean"},"requiresGuardianUnder":{"type":"integer"},"requiresUpload":{"type":"boolean"}},"required":["kind","title","bodyHtml"]}}}}}},"/forms/{formId}":{"patch":{"tags":["Forms"],"summary":"Update a form template (a body change bumps its version)","description":"Requires write scope (organizer/staff).","operationId":"patch_forms_formId","parameters":[{"name":"formId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string"},"title":{"type":"string"},"bodyHtml":{"type":"string"},"required":{"type":"boolean"},"requiresGuardianUnder":{"type":"integer"},"requiresUpload":{"type":"boolean"},"active":{"type":"boolean"}}}}}}}},"/forms/{formId}/signatures":{"get":{"tags":["Forms"],"summary":"List signatures for a form","description":"Requires write scope (organizer/staff).","operationId":"get_forms_formId_signatures","parameters":[{"name":"formId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/forms/{formId}/sign":{"post":{"tags":["Forms"],"summary":"Sign a form (public)","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"post_forms_formId_sign","parameters":[{"name":"formId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fencerId":{"type":"integer"},"signerName":{"type":"string"},"guardianName":{"type":"string"},"guardianRelationship":{"type":"string"},"signatureText":{"type":"string"},"uploadUrl":{"type":"string"}},"required":["fencerId","signerName","signatureText"]}}}}}},"/tournaments/{tid}/fencers/{fid}/forms-status":{"get":{"tags":["Forms"],"summary":"Whether a fencer's required forms are complete","description":"Requires read access.","operationId":"get_tournaments_tid_fencers_fid_forms_status","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"fid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/checkin":{"get":{"tags":["Check-in"],"summary":"Entries across events with check-in blockers","description":"Requires write scope (organizer/staff).","operationId":"get_tournaments_tid_checkin","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/entries/{entryId}/checkin":{"post":{"tags":["Check-in"],"summary":"Check an entry in (409 checkin_blocked unless override)","description":"Requires write scope (organizer/staff).","operationId":"post_entries_entryId_checkin","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"override":{"type":"boolean"}}}}}}}},"/entries/{entryId}/checkout":{"post":{"tags":["Check-in"],"summary":"Undo a check-in","description":"Requires write scope (organizer/staff).","operationId":"post_entries_entryId_checkout","parameters":[{"name":"entryId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/audit":{"get":{"tags":["Tournaments"],"summary":"Audit log for a tournament","description":"Requires write scope (organizer/staff).","operationId":"get_tournaments_tid_audit","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/settings":{"get":{"tags":["Meta"],"summary":"Read server settings (superadmin)","description":"Requires admin scope / org owner or organizer.","operationId":"get_settings","parameters":[],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]},"put":{"tags":["Meta"],"summary":"Update server settings (superadmin)","description":"Requires admin scope / org owner or organizer.","operationId":"put_settings","parameters":[],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"settings":{"type":"object","additionalProperties":true}},"required":["settings"]}}}}}},"/events/{eid}/seed":{"post":{"tags":["Pools"],"summary":"Seed checked-in entries by rating or a manual order","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_seed","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"method":{"type":"string","enum":["rating","manual"]},"order":{"type":"array","items":{"type":"integer"}}}}}}}}},"/events/{eid}/pools/generate":{"post":{"tags":["Pools"],"summary":"Generate pools and all pool bouts","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_pools_generate","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"poolSize":{"type":"integer"},"poolCount":{"type":"integer"},"separateClubs":{"type":"boolean"},"stripStart":{"type":"integer"}}}}}}}},"/events/{eid}/pools":{"get":{"tags":["Pools"],"summary":"Pools with members, bout matrix and per-fencer stats","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid_pools","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/pools/{poolId}":{"get":{"tags":["Pools"],"summary":"One pool sheet","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_pools_poolId","parameters":[{"name":"poolId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/pools/{poolId}/assign":{"post":{"tags":["Pools"],"summary":"Assign a pool to a strip and referee","description":"Requires write scope (organizer/staff).","operationId":"post_pools_poolId_assign","parameters":[{"name":"poolId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"strip":{"type":"integer"},"referee":{"type":"string"}}}}}}}},"/events/{eid}/pools/finalize":{"post":{"tags":["Pools"],"summary":"Finalize pools: compute pool seed and cut by promotion percentage","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_pools_finalize","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/events/{eid}/pools/results":{"get":{"tags":["Pools"],"summary":"Ranked pool results with advanced/eliminated","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid_pools_results","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/events/{eid}/tableau/generate":{"post":{"tags":["Tableau & results"],"summary":"Generate the direct-elimination tableau","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_tableau_generate","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/events/{eid}/tableau":{"get":{"tags":["Tableau & results"],"summary":"Tableau rounds and bouts","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid_tableau","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/events/{eid}/tableau/reset-bout/{boutId}":{"post":{"tags":["Tableau & results"],"summary":"Reset a tableau bout and everything downstream (requires confirm=true)","description":"Requires write scope (organizer/staff).","operationId":"post_events_eid_tableau_reset_bout_boutId","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}},{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/events/{eid}/results":{"get":{"tags":["Tableau & results"],"summary":"Final standings","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_events_eid_results","parameters":[{"name":"eid","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/tournaments/{tid}/strips":{"get":{"tags":["Strips"],"summary":"Strips with current and on-deck bouts","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_strips","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Strips"],"summary":"Create strips by count or one by number","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_strips","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"number":{"type":"integer"},"label":{"type":"string"},"location":{"type":"string"}}}}}}}},"/tournaments/{tid}/strips/{n}":{"patch":{"tags":["Strips"],"summary":"Update a strip","description":"Requires write scope (organizer/staff).","operationId":"patch_tournaments_tid_strips_n","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["idle","live","hold","offline"]},"label":{"type":"string"},"location":{"type":"string"},"hasVideo":{"type":"boolean"}}}}}}}},"/tournaments/{tid}/queue":{"get":{"tags":["Strips"],"summary":"Bouts ready to fence, in order","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_queue","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/tournaments/{tid}/strips/auto-assign":{"post":{"tags":["Strips"],"summary":"Fill idle strips from the queue","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_strips_auto_assign","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/bouts/{boutId}":{"get":{"tags":["Bouts"],"summary":"Bout state (the canonical BoutState)","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_bouts_boutId","parameters":[{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoutEnvelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/bouts/{boutId}/events":{"get":{"tags":["Bouts"],"summary":"Touch log for a bout","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_bouts_boutId_events","parameters":[{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Bouts"],"summary":"Apply a scoring event (touch, card, clock, complete…)","description":"Requires score scope (or a scorekeeper/referee grant).","operationId":"post_bouts_boutId_events","parameters":[{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["score"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["score"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["touch","score_set","card","clock","status","lamp","priority","sign","complete","reopen","assign"]},"side":{"type":"string","enum":["left","right"]},"delta":{"type":"integer"},"left":{"type":"integer"},"right":{"type":"integer"},"color":{"type":"string","enum":["yellow","red","black"]},"remainingMs":{"type":"integer"},"running":{"type":"boolean"},"period":{"type":"integer"},"status":{"type":"string","enum":["scheduled","called","on_strip","live","complete","canceled"]},"red":{"type":"boolean"},"green":{"type":"boolean"},"who":{"type":"string","enum":["left","right","referee"]},"winner":{"type":"string","enum":["left","right"]},"value":{"type":"boolean"},"awardTouch":{"type":"boolean"},"expectedVersion":{"type":"integer"},"clientId":{"type":"string"},"maxTouches":{"type":"integer"},"strip":{"type":"integer"},"referee":{"type":"string"}},"required":["type"]}}}}}},"/bouts/{boutId}/assign":{"post":{"tags":["Bouts"],"summary":"Assign a bout to a strip and referee","description":"Requires write scope (organizer/staff).","operationId":"post_bouts_boutId_assign","parameters":[{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"strip":{"type":"integer"},"referee":{"type":"string"}}}}}}}},"/bouts/{boutId}/call":{"post":{"tags":["Bouts"],"summary":"Call a bout to a strip","description":"Requires write scope (organizer/staff).","operationId":"post_bouts_boutId_call","parameters":[{"name":"boutId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"strip":{"type":"integer"}}}}}}}},"/tournaments/{tid}/bouts":{"get":{"tags":["Bouts"],"summary":"List bouts","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_bouts","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"strip","in":"query","required":false,"schema":{"type":"integer"}},{"name":"eventId","in":"query","required":false,"schema":{"type":"integer"}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["pool","de"]}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/tournaments/{tid}/broadcast-config":{"get":{"tags":["Broadcast"],"summary":"Broadcast configuration merged with settings","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_broadcast_config","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"put":{"tags":["Broadcast"],"summary":"Replace the broadcast configuration","description":"Requires write scope (organizer/staff).","operationId":"put_tournaments_tid_broadcast_config","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rotation":{"type":"array","items":{"type":"object","additionalProperties":true}},"scrollPxPerSec":{"type":"integer"},"categoryDwellSec":{"type":"integer"},"pagePauseSec":{"type":"integer"},"theme":{"type":"string"}}}}}}}},"/tournaments/{tid}/display-urls":{"get":{"tags":["Broadcast"],"summary":"Ready-made display URLs per view","description":"Requires read access.","operationId":"get_tournaments_tid_display_urls","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/broadcaster/heartbeat":{"post":{"tags":["Broadcast"],"summary":"Broadcaster app heartbeat with its outputs","description":"Requires the broadcast scope.","operationId":"post_tournaments_tid_broadcaster_heartbeat","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["broadcast"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["broadcast"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deviceName":{"type":"string"},"outputs":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["deviceName","outputs"]}}}}}},"/tournaments/{tid}/broadcaster/outputs":{"get":{"tags":["Broadcast"],"summary":"Broadcaster outputs with stale flag","description":"Requires read access.","operationId":"get_tournaments_tid_broadcaster_outputs","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/snapstudio":{"get":{"tags":["Broadcast"],"summary":"SnapStudio Tournament export","description":"Requires read access.","operationId":"get_tournaments_tid_snapstudio","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["read"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/strips/{n}/machine":{"post":{"tags":["Broadcast"],"summary":"Machine ingest: update the bout on a strip from SnapStudio, Broadcaster or Cyrano","description":"Requires score scope (or a scorekeeper/referee grant).","operationId":"post_tournaments_tid_strips_n_machine","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"n","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["score"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["score"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"source":{"type":"string","enum":["snapstudio","broadcaster","cyrano"]},"leftScore":{"type":"integer"},"rightScore":{"type":"integer"},"lamps":{"type":"object","additionalProperties":true},"clockMs":{"type":"integer"},"clockRunning":{"type":"boolean"},"cards":{"type":"object","additionalProperties":true},"period":{"type":"integer"},"priority":{"type":"string","enum":["left","right"]}},"required":["source"]}}}}}},"/tournaments/{tid}/ticket-types":{"get":{"tags":["Tickets"],"summary":"List ticket types","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_tournaments_tid_ticket_types","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]},"post":{"tags":["Tickets"],"summary":"Create a ticket type","description":"Requires write scope (organizer/staff).","operationId":"post_tournaments_tid_ticket_types","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"priceCents":{"type":"integer"},"quantity":{"type":"integer"},"validDate":{"type":"string","format":"date"},"salesStart":{"type":"string","format":"date-time"},"salesEnd":{"type":"string","format":"date-time"},"active":{"type":"boolean"},"sortOrder":{"type":"integer"}},"required":["name"]}}}}}},"/ticket-types/{id}":{"patch":{"tags":["Tickets"],"summary":"Update a ticket type","description":"Requires write scope (organizer/staff).","operationId":"patch_ticket_types_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"priceCents":{"type":"integer"},"quantity":{"type":"integer"},"validDate":{"type":"string","format":"date"},"salesStart":{"type":"string","format":"date-time"},"salesEnd":{"type":"string","format":"date-time"},"active":{"type":"boolean"},"sortOrder":{"type":"integer"}}}}}}},"delete":{"tags":["Tickets"],"summary":"Delete a ticket type (deactivates it if tickets were sold)","description":"Requires write scope (organizer/staff).","operationId":"delete_ticket_types_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tournaments/{tid}/checkout":{"post":{"tags":["Tickets"],"summary":"Buy tickets (public). Returns a Stripe Checkout URL, or a confirmation URL for free orders","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"post_tournaments_tid_checkout","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"buyerName":{"type":"string"},"buyerEmail":{"type":"string"},"items":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["buyerName","buyerEmail","items"]}}}}}},"/tournaments/{tid}/orders":{"get":{"tags":["Tickets"],"summary":"List ticket orders","description":"Requires write scope (organizer/staff).","operationId":"get_tournaments_tid_orders","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/orders/{orderId}/refund":{"post":{"tags":["Tickets"],"summary":"Refund an order and void its tickets (requires confirm=true)","description":"Requires write scope (organizer/staff).","operationId":"post_orders_orderId_refund","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/tickets/scan":{"post":{"tags":["Tickets"],"summary":"Scan a ticket code at the door","description":"Requires score scope (or a scorekeeper/referee grant).","operationId":"post_tickets_scan","parameters":[],"x-scopes":["score"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["score"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}}}},"/tournaments/{tid}/tickets/summary":{"get":{"tags":["Tickets"],"summary":"Tickets sold, revenue and scans by type","description":"Requires write scope (organizer/staff).","operationId":"get_tournaments_tid_tickets_summary","parameters":[{"name":"tid","in":"path","required":true,"description":"Tournament numeric id or slug","schema":{"type":"string"}}],"x-scopes":["write"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["write"]},{"cookieAuth":[]}]}},"/orgs/{orgId}/stripe/connect":{"post":{"tags":["Tickets"],"summary":"Start Stripe Connect onboarding; returns the onboarding link","description":"Requires admin scope / org owner or organizer.","operationId":"post_orgs_orgId_stripe_connect","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"returnTo":{"type":"string"}}}}}}}},"/orgs/{orgId}/api-keys":{"get":{"tags":["API keys"],"summary":"List API keys (never the secrets)","description":"Requires admin scope / org owner or organizer.","operationId":"get_orgs_orgId_api_keys","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]},"post":{"tags":["API keys"],"summary":"Create an API key; the key is shown once","description":"Requires admin scope / org owner or organizer.","operationId":"post_orgs_orgId_api_keys","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"tournamentId":{"type":"integer"}},"required":["name"]}}}}}},"/api-keys/{id}":{"delete":{"tags":["API keys"],"summary":"Revoke an API key (requires confirm=true)","description":"Requires admin scope / org owner or organizer.","operationId":"delete_api_keys_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"boolean"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]}},"/orgs/{orgId}/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks","description":"Requires admin scope / org owner or organizer.","operationId":"get_orgs_orgId_webhooks","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]},"post":{"tags":["Webhooks"],"summary":"Create a webhook","description":"Requires admin scope / org owner or organizer.","operationId":"post_orgs_orgId_webhooks","parameters":[{"name":"orgId","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"tournamentId":{"type":"integer"},"active":{"type":"boolean"}},"required":["url"]}}}}}},"/webhooks/{id}":{"patch":{"tags":["Webhooks"],"summary":"Update a webhook","description":"Requires admin scope / org owner or organizer.","operationId":"patch_webhooks_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"tournamentId":{"type":"integer"},"active":{"type":"boolean"}}}}}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook","description":"Requires admin scope / org owner or organizer.","operationId":"delete_webhooks_id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]}},"/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Send a test delivery","description":"Requires admin scope / org owner or organizer.","operationId":"post_webhooks_id_test","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"x-scopes":["admin"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["admin"]},{"cookieAuth":[]}]}},"/whoami":{"get":{"tags":["Meta"],"summary":"Describe the caller: API key name, scopes, organization and tournament limit","description":"Requires a signed-in user or API key.","operationId":"get_whoami","parameters":[],"x-scopes":["user"],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{"bearerAuth":["read"]},{"cookieAuth":[]}]}},"/openapi.json":{"get":{"tags":["Meta"],"summary":"This OpenAPI 3.1 document","description":"Public for published/live/completed tournaments; otherwise needs read access.","operationId":"get_openapi_json","parameters":[],"x-scopes":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}},"security":[{},{"bearerAuth":[]},{"cookieAuth":[]}]}},"/stripe/webhook":{"post":{"tags":["Tickets"],"summary":"Stripe webhook receiver (outside /api/v1; verified with STRIPE_WEBHOOK_SECRET)","servers":[{"url":"https://fencing.lumenaproductions.com"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Received"},"400":{"description":"Bad signature"},"503":{"description":"Stripe not configured"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"fs_… API key","description":"Scopes: read, write, score, broadcast, admin."},"cookieAuth":{"type":"apiKey","in":"cookie","name":"connect.sid","description":"Browser session cookie."}},"schemas":{"Envelope":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean"},"data":{}}},"ErrorEnvelope":{"type":"object","required":["ok","error"],"properties":{"ok":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}},"BoutSide":{"type":"object","properties":{"entryId":{"type":"integer"},"fencerId":{"type":"integer"},"name":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"club":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"rating":{"type":"string","nullable":true},"seed":{"type":"integer","nullable":true},"photoUrl":{"type":["string","null"]},"score":{"type":"integer"},"cards":{"type":"object","properties":{"yellow":{"type":"integer"},"red":{"type":"integer"},"black":{"type":"integer"}}}}},"BoutState":{"type":"object","description":"Canonical bout state used by every channel. Left = red lamp, right = green lamp.","properties":{"id":{"type":"integer"},"tournamentId":{"type":"integer"},"eventId":{"type":"integer"},"eventName":{"type":"string"},"weapon":{"type":"string","enum":["foil","epee","saber"]},"kind":{"type":"string","enum":["pool","de"]},"round":{"type":["string","null"],"example":"T32"},"roundSize":{"type":["integer","null"]},"slot":{"type":["integer","null"]},"poolNumber":{"type":["integer","null"]},"boutOrder":{"type":["integer","null"]},"strip":{"type":["integer","null"]},"status":{"type":"string","enum":["scheduled","called","on_strip","live","complete","canceled"]},"period":{"type":"integer"},"clock":{"type":"object","properties":{"remainingMs":{"type":["integer","null"]},"running":{"type":"boolean"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"priority":{"type":["string","null"],"enum":["left","right",null]},"left":{"$ref":"#/components/schemas/BoutSide"},"right":{"$ref":"#/components/schemas/BoutSide"},"lamps":{"type":"object","properties":{"red":{"type":"boolean"},"green":{"type":"boolean"}}},"maxTouches":{"type":"integer"},"winner":{"type":["string","null"]},"isBye":{"type":"boolean"},"referee":{"type":["string","null"]},"signed":{"type":"object","properties":{"left":{"type":"boolean"},"right":{"type":"boolean"},"referee":{"type":"boolean"}}},"media":{"type":"array","items":{"type":"object"}},"calledAt":{"type":["string","null"],"format":"date-time"},"startedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"version":{"type":"integer"},"updatedAt":{"type":"string","format":"date-time"}}},"BoutEnvelope":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"$ref":"#/components/schemas/BoutState"}}}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}