> For the complete documentation index, see [llms.txt](https://movemint.gitbook.io/movemint-developer-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://movemint.gitbook.io/movemint-developer-docs/open-api-specification/core-resources/sub-events.md).

# Sub Events

Manage sub-events (race distances / categories) inside an event. Pricing tiers, gender restrictions, and waitlist settings are configured per sub-event.

## List sub-events

> Returns all sub-events (race distances / categories) for the event,\
> in display order.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Sub-events","description":"Manage sub-events (race distances / categories) inside an event.\nPricing tiers, gender restrictions, and waitlist settings are\nconfigured per sub-event.\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"parameters":{"EventHandle":{"name":"handle","in":"path","required":true,"description":"The unique handle (slug) of the event","schema":{"type":"string"}}},"schemas":{"SubEvent":{"type":"object","required":["id","name","description","start_date","end_date","start_time","end_time","registration_open_date","registration_close_date","order","max_participants","min_age","max_age","allow_race_day_registration","race_day_price_cents","hidden","invite_only","requires_login","show_spots_remaining","multiple_registration","has_waitlist","require_applications","waitlist_auto_invite_enabled","waitlist_invite_response_window_hours","waitlist_under_capacity_grace_period_minutes","waitlist_invite_cutoff_at","has_multiple_participants","multi_participant_count","multi_participant_max_count","allowed_gender_ids","registration_code_set","distance","distance_meters","distance_display_unit","formatted_distance","prices"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"start_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"end_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time","nullable":true},"registration_close_date":{"type":"string","format":"date-time","nullable":true},"order":{"type":"integer","nullable":true},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean","nullable":true},"race_day_price_cents":{"type":"integer","nullable":true},"hidden":{"type":"boolean","nullable":true},"invite_only":{"type":"boolean","nullable":true},"requires_login":{"type":"boolean","description":"Whether athletes must be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean","nullable":true},"multiple_registration":{"type":"boolean","nullable":true},"has_waitlist":{"type":"boolean","nullable":true},"require_applications":{"type":"boolean","description":"When true, every registrant enters the waitlist/application flow for\nthis sub-event regardless of remaining capacity. Surfaced to athletes\nas an application rather than a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean","nullable":true},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean","nullable":true},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"allowed_gender_ids":{"type":"array","nullable":true,"description":"Array of `GenderIdentity` integer IDs that may register for this\nsub-event. `null` means all genders are allowed.\n","items":{"type":"integer"}},"registration_code_set":{"type":"boolean","description":"Whether a private registration code is configured."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance expressed in `distance_display_unit` (e.g. 13.1\nwhen the unit is `miles`). This is the value to send back on a write.\n"},"distance_meters":{"type":"integer","nullable":true,"description":"Sub-event distance normalized to meters. This is the canonical,\nqueryable value; `distance_display_unit` records the unit it was\nentered in.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Display unit the organizer entered the distance in."},"formatted_distance":{"type":"string","nullable":true,"description":"Preformatted distance in the display unit, e.g. `\"13.1 mi\"`."},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPrice"}}}},"SubEventPrice":{"type":"object","required":["id","price_cents","price_dollars","is_sliding_scale","close_date","description"],"properties":{"id":{"type":"integer","format":"int64"},"price_cents":{"type":"integer","description":"Tier price in the event's currency, in minor units (cents)."},"price_dollars":{"type":"number","format":"double","description":"Convenience copy of `price_cents` divided by 100."},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true,"description":"When this tier ends. Null on the final/highest tier."},"description":{"type":"string","nullable":true}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}},"Error":{"type":"object","description":"A generic error response","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}}},"responses":{"Unauthorized":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"Forbidden":{"description":"Forbidden - user is not an admin of this event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"EventNotFound":{"description":"Event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/events/{handle}/sub_events":{"get":{"tags":["Sub-events"],"summary":"List sub-events","description":"Returns all sub-events (race distances / categories) for the event,\nin display order.\n","operationId":"listSubEvents","parameters":[{"$ref":"#/components/parameters/EventHandle"}],"responses":{"200":{"description":"Ordered list of sub-events","content":{"application/json":{"schema":{"type":"object","required":["sub_events"],"properties":{"sub_events":{"type":"array","items":{"$ref":"#/components/schemas/SubEvent"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/EventNotFound"}}}}}}
````

## Create a sub-event

> Creates a new sub-event under the parent event. Pricing tiers can be\
> supplied inline via \`prices\` (full tiered shape) or as a single-tier\
> shorthand via \`price\_cents\` / \`price\_dollars\`. Gender restrictions\
> accept an array of \`GenderIdentity\` IDs (\`allowed\_gender\_ids\`) — an\
> empty array or omitted key means "all allowed".<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Sub-events","description":"Manage sub-events (race distances / categories) inside an event.\nPricing tiers, gender restrictions, and waitlist settings are\nconfigured per sub-event.\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"parameters":{"EventHandle":{"name":"handle","in":"path","required":true,"description":"The unique handle (slug) of the event","schema":{"type":"string"}}},"schemas":{"CreateSubEventRequest":{"allOf":[{"$ref":"#/components/schemas/SubEventWritableFields"},{"type":"object","required":["name"]}]},"SubEventWritableFields":{"type":"object","description":"Fields accepted by sub-event create/update. Direct date/time fields\naccept ISO-8601 strings (`YYYY-MM-DD` for dates, `HH:MM` for\ntimes-of-day, full ISO-8601 for datetimes).\n\n**Pricing.** Send `prices` for tiered pricing, OR `price_cents` /\n`price_dollars` as a single-tier shorthand. Supplying any of these\nreplaces the existing tier set entirely.\n\n**Gender restrictions.** `allowed_gender_ids` is an array of\n`GenderIdentity` integer IDs. Empty / omitted means \"all allowed\".\n","properties":{"name":{"type":"string"},"description":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"start_time":{"type":"string","description":"24-hour `HH:MM`."},"end_time":{"type":"string","description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time"},"registration_close_date":{"type":"string","format":"date-time"},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean"},"race_day_price":{"type":"integer","description":"Race-day price in minor units (cents)."},"race_day_price_cents":{"type":"integer"},"race_day_price_dollars":{"type":"number","format":"double"},"hidden":{"type":"boolean"},"invite_only":{"type":"boolean"},"requires_login":{"type":"boolean","description":"Require athletes to be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean"},"multiple_registration":{"type":"boolean"},"has_waitlist":{"type":"boolean"},"require_applications":{"type":"boolean","description":"Force every registrant into the waitlist/application flow regardless\nof capacity. Surfaced to athletes as an application, not a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean"},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean"},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"registration_code":{"type":"string","description":"Empty string clears."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance as a value in `distance_display_unit` (e.g. 13.1\nwith unit `miles`, or 5 with `kilometers`). Normalized to meters\nserver-side so the entered value round-trips. Send together with\n`distance_display_unit`; a blank value clears the distance.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Unit the `distance` value is in and displays in. Required when\n`distance` is set.\n"},"allowed_gender_ids":{"type":"array","items":{"type":"integer"}},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPriceTierInput"}},"price_cents":{"type":"integer","description":"Single-tier shorthand. Mutually exclusive with `prices`."},"price_dollars":{"type":"number","format":"double","description":"Single-tier shorthand. Mutually exclusive with `prices`."}}},"SubEventPriceTierInput":{"type":"object","description":"One pricing tier. Provide either `price_cents` or `price_dollars`\n(not both). Tiers without a `close_date` represent the final /\nhighest tier.\n","properties":{"price_cents":{"type":"integer"},"price_dollars":{"type":"number","format":"double"},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true},"description":{"type":"string","nullable":true}}},"SubEvent":{"type":"object","required":["id","name","description","start_date","end_date","start_time","end_time","registration_open_date","registration_close_date","order","max_participants","min_age","max_age","allow_race_day_registration","race_day_price_cents","hidden","invite_only","requires_login","show_spots_remaining","multiple_registration","has_waitlist","require_applications","waitlist_auto_invite_enabled","waitlist_invite_response_window_hours","waitlist_under_capacity_grace_period_minutes","waitlist_invite_cutoff_at","has_multiple_participants","multi_participant_count","multi_participant_max_count","allowed_gender_ids","registration_code_set","distance","distance_meters","distance_display_unit","formatted_distance","prices"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"start_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"end_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time","nullable":true},"registration_close_date":{"type":"string","format":"date-time","nullable":true},"order":{"type":"integer","nullable":true},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean","nullable":true},"race_day_price_cents":{"type":"integer","nullable":true},"hidden":{"type":"boolean","nullable":true},"invite_only":{"type":"boolean","nullable":true},"requires_login":{"type":"boolean","description":"Whether athletes must be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean","nullable":true},"multiple_registration":{"type":"boolean","nullable":true},"has_waitlist":{"type":"boolean","nullable":true},"require_applications":{"type":"boolean","description":"When true, every registrant enters the waitlist/application flow for\nthis sub-event regardless of remaining capacity. Surfaced to athletes\nas an application rather than a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean","nullable":true},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean","nullable":true},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"allowed_gender_ids":{"type":"array","nullable":true,"description":"Array of `GenderIdentity` integer IDs that may register for this\nsub-event. `null` means all genders are allowed.\n","items":{"type":"integer"}},"registration_code_set":{"type":"boolean","description":"Whether a private registration code is configured."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance expressed in `distance_display_unit` (e.g. 13.1\nwhen the unit is `miles`). This is the value to send back on a write.\n"},"distance_meters":{"type":"integer","nullable":true,"description":"Sub-event distance normalized to meters. This is the canonical,\nqueryable value; `distance_display_unit` records the unit it was\nentered in.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Display unit the organizer entered the distance in."},"formatted_distance":{"type":"string","nullable":true,"description":"Preformatted distance in the display unit, e.g. `\"13.1 mi\"`."},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPrice"}}}},"SubEventPrice":{"type":"object","required":["id","price_cents","price_dollars","is_sliding_scale","close_date","description"],"properties":{"id":{"type":"integer","format":"int64"},"price_cents":{"type":"integer","description":"Tier price in the event's currency, in minor units (cents)."},"price_dollars":{"type":"number","format":"double","description":"Convenience copy of `price_cents` divided by 100."},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true,"description":"When this tier ends. Null on the final/highest tier."},"description":{"type":"string","nullable":true}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}},"Error":{"type":"object","description":"A generic error response","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}},"ValidationError":{"type":"object","description":"A validation error response with a list of error messages","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"string"},"description":"List of validation error messages"}}}},"responses":{"Unauthorized":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"Forbidden":{"description":"Forbidden - user is not an admin of this event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"EventNotFound":{"description":"Event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/events/{handle}/sub_events":{"post":{"tags":["Sub-events"],"summary":"Create a sub-event","description":"Creates a new sub-event under the parent event. Pricing tiers can be\nsupplied inline via `prices` (full tiered shape) or as a single-tier\nshorthand via `price_cents` / `price_dollars`. Gender restrictions\naccept an array of `GenderIdentity` IDs (`allowed_gender_ids`) — an\nempty array or omitted key means \"all allowed\".\n","operationId":"createSubEvent","parameters":[{"$ref":"#/components/parameters/EventHandle"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubEventRequest"}}}},"responses":{"201":{"description":"Sub-event created","content":{"application/json":{"schema":{"type":"object","required":["sub_event"],"properties":{"sub_event":{"$ref":"#/components/schemas/SubEvent"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/EventNotFound"},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}}}}
````

## GET /api/v1/events/{handle}/sub\_events/{id}

> Get a sub-event

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Sub-events","description":"Manage sub-events (race distances / categories) inside an event.\nPricing tiers, gender restrictions, and waitlist settings are\nconfigured per sub-event.\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"parameters":{"EventHandle":{"name":"handle","in":"path","required":true,"description":"The unique handle (slug) of the event","schema":{"type":"string"}},"ResourceId":{"name":"id","in":"path","required":true,"description":"The ID of the resource","schema":{"type":"integer","format":"int64"}}},"schemas":{"SubEvent":{"type":"object","required":["id","name","description","start_date","end_date","start_time","end_time","registration_open_date","registration_close_date","order","max_participants","min_age","max_age","allow_race_day_registration","race_day_price_cents","hidden","invite_only","requires_login","show_spots_remaining","multiple_registration","has_waitlist","require_applications","waitlist_auto_invite_enabled","waitlist_invite_response_window_hours","waitlist_under_capacity_grace_period_minutes","waitlist_invite_cutoff_at","has_multiple_participants","multi_participant_count","multi_participant_max_count","allowed_gender_ids","registration_code_set","distance","distance_meters","distance_display_unit","formatted_distance","prices"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"start_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"end_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time","nullable":true},"registration_close_date":{"type":"string","format":"date-time","nullable":true},"order":{"type":"integer","nullable":true},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean","nullable":true},"race_day_price_cents":{"type":"integer","nullable":true},"hidden":{"type":"boolean","nullable":true},"invite_only":{"type":"boolean","nullable":true},"requires_login":{"type":"boolean","description":"Whether athletes must be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean","nullable":true},"multiple_registration":{"type":"boolean","nullable":true},"has_waitlist":{"type":"boolean","nullable":true},"require_applications":{"type":"boolean","description":"When true, every registrant enters the waitlist/application flow for\nthis sub-event regardless of remaining capacity. Surfaced to athletes\nas an application rather than a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean","nullable":true},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean","nullable":true},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"allowed_gender_ids":{"type":"array","nullable":true,"description":"Array of `GenderIdentity` integer IDs that may register for this\nsub-event. `null` means all genders are allowed.\n","items":{"type":"integer"}},"registration_code_set":{"type":"boolean","description":"Whether a private registration code is configured."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance expressed in `distance_display_unit` (e.g. 13.1\nwhen the unit is `miles`). This is the value to send back on a write.\n"},"distance_meters":{"type":"integer","nullable":true,"description":"Sub-event distance normalized to meters. This is the canonical,\nqueryable value; `distance_display_unit` records the unit it was\nentered in.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Display unit the organizer entered the distance in."},"formatted_distance":{"type":"string","nullable":true,"description":"Preformatted distance in the display unit, e.g. `\"13.1 mi\"`."},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPrice"}}}},"SubEventPrice":{"type":"object","required":["id","price_cents","price_dollars","is_sliding_scale","close_date","description"],"properties":{"id":{"type":"integer","format":"int64"},"price_cents":{"type":"integer","description":"Tier price in the event's currency, in minor units (cents)."},"price_dollars":{"type":"number","format":"double","description":"Convenience copy of `price_cents` divided by 100."},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true,"description":"When this tier ends. Null on the final/highest tier."},"description":{"type":"string","nullable":true}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}},"Error":{"type":"object","description":"A generic error response","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}}},"responses":{"Unauthorized":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"Forbidden":{"description":"Forbidden - user is not an admin of this event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubEventNotFound":{"description":"Event or sub-event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/events/{handle}/sub_events/{id}":{"get":{"tags":["Sub-events"],"summary":"Get a sub-event","operationId":"getSubEvent","parameters":[{"$ref":"#/components/parameters/EventHandle"},{"$ref":"#/components/parameters/ResourceId"}],"responses":{"200":{"description":"Sub-event details","content":{"application/json":{"schema":{"type":"object","required":["sub_event"],"properties":{"sub_event":{"$ref":"#/components/schemas/SubEvent"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/SubEventNotFound"}}}}}}
````

## Delete a sub-event

> Permanently deletes the sub-event. Sub-events that already have\
> registered participants cannot be deleted; the response is \`422\` in\
> that case.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Sub-events","description":"Manage sub-events (race distances / categories) inside an event.\nPricing tiers, gender restrictions, and waitlist settings are\nconfigured per sub-event.\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"parameters":{"EventHandle":{"name":"handle","in":"path","required":true,"description":"The unique handle (slug) of the event","schema":{"type":"string"}},"ResourceId":{"name":"id","in":"path","required":true,"description":"The ID of the resource","schema":{"type":"integer","format":"int64"}}},"responses":{"Unauthorized":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"Forbidden":{"description":"Forbidden - user is not an admin of this event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubEventNotFound":{"description":"Event or sub-event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}},"Error":{"type":"object","description":"A generic error response","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}}}},"paths":{"/api/v1/events/{handle}/sub_events/{id}":{"delete":{"tags":["Sub-events"],"summary":"Delete a sub-event","description":"Permanently deletes the sub-event. Sub-events that already have\nregistered participants cannot be deleted; the response is `422` in\nthat case.\n","operationId":"deleteSubEvent","parameters":[{"$ref":"#/components/parameters/EventHandle"},{"$ref":"#/components/parameters/ResourceId"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","enum":[true]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/SubEventNotFound"},"422":{"description":"Has participants","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
````

## Update a sub-event

> Partially update a sub-event. Fields not present in the request are\
> left untouched. Sending an explicit \`null\` (or empty string for\
> strings) clears a value where the field is nullable. Pricing\
> tiers — when supplied — completely replace the existing tiers.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Sub-events","description":"Manage sub-events (race distances / categories) inside an event.\nPricing tiers, gender restrictions, and waitlist settings are\nconfigured per sub-event.\n"}],"servers":[{"url":"https://www.movemint.cc","description":"Production"}],"security":[{"bearerAuth":[]},{"oauth2":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Pass the access token in the `Authorization` header:\n```\nAuthorization: Bearer YOUR_ACCESS_TOKEN\n```\n"},"oauth2":{"type":"oauth2","description":"OAuth 2.0 authentication using the Authorization Code or Client\nCredentials grant flow.\n","flows":{"authorizationCode":{"authorizationUrl":"https://www.movemint.cc/oauth/authorize","tokenUrl":"https://www.movemint.cc/oauth/token","refreshUrl":"https://www.movemint.cc/oauth/token","scopes":{}},"clientCredentials":{"tokenUrl":"https://www.movemint.cc/oauth/token","scopes":{}}}}},"parameters":{"EventHandle":{"name":"handle","in":"path","required":true,"description":"The unique handle (slug) of the event","schema":{"type":"string"}},"ResourceId":{"name":"id","in":"path","required":true,"description":"The ID of the resource","schema":{"type":"integer","format":"int64"}}},"schemas":{"UpdateSubEventRequest":{"$ref":"#/components/schemas/SubEventWritableFields"},"SubEventWritableFields":{"type":"object","description":"Fields accepted by sub-event create/update. Direct date/time fields\naccept ISO-8601 strings (`YYYY-MM-DD` for dates, `HH:MM` for\ntimes-of-day, full ISO-8601 for datetimes).\n\n**Pricing.** Send `prices` for tiered pricing, OR `price_cents` /\n`price_dollars` as a single-tier shorthand. Supplying any of these\nreplaces the existing tier set entirely.\n\n**Gender restrictions.** `allowed_gender_ids` is an array of\n`GenderIdentity` integer IDs. Empty / omitted means \"all allowed\".\n","properties":{"name":{"type":"string"},"description":{"type":"string"},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"start_time":{"type":"string","description":"24-hour `HH:MM`."},"end_time":{"type":"string","description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time"},"registration_close_date":{"type":"string","format":"date-time"},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean"},"race_day_price":{"type":"integer","description":"Race-day price in minor units (cents)."},"race_day_price_cents":{"type":"integer"},"race_day_price_dollars":{"type":"number","format":"double"},"hidden":{"type":"boolean"},"invite_only":{"type":"boolean"},"requires_login":{"type":"boolean","description":"Require athletes to be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean"},"multiple_registration":{"type":"boolean"},"has_waitlist":{"type":"boolean"},"require_applications":{"type":"boolean","description":"Force every registrant into the waitlist/application flow regardless\nof capacity. Surfaced to athletes as an application, not a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean"},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean"},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"registration_code":{"type":"string","description":"Empty string clears."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance as a value in `distance_display_unit` (e.g. 13.1\nwith unit `miles`, or 5 with `kilometers`). Normalized to meters\nserver-side so the entered value round-trips. Send together with\n`distance_display_unit`; a blank value clears the distance.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Unit the `distance` value is in and displays in. Required when\n`distance` is set.\n"},"allowed_gender_ids":{"type":"array","items":{"type":"integer"}},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPriceTierInput"}},"price_cents":{"type":"integer","description":"Single-tier shorthand. Mutually exclusive with `prices`."},"price_dollars":{"type":"number","format":"double","description":"Single-tier shorthand. Mutually exclusive with `prices`."}}},"SubEventPriceTierInput":{"type":"object","description":"One pricing tier. Provide either `price_cents` or `price_dollars`\n(not both). Tiers without a `close_date` represent the final /\nhighest tier.\n","properties":{"price_cents":{"type":"integer"},"price_dollars":{"type":"number","format":"double"},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true},"description":{"type":"string","nullable":true}}},"SubEvent":{"type":"object","required":["id","name","description","start_date","end_date","start_time","end_time","registration_open_date","registration_close_date","order","max_participants","min_age","max_age","allow_race_day_registration","race_day_price_cents","hidden","invite_only","requires_login","show_spots_remaining","multiple_registration","has_waitlist","require_applications","waitlist_auto_invite_enabled","waitlist_invite_response_window_hours","waitlist_under_capacity_grace_period_minutes","waitlist_invite_cutoff_at","has_multiple_participants","multi_participant_count","multi_participant_max_count","allowed_gender_ids","registration_code_set","distance","distance_meters","distance_display_unit","formatted_distance","prices"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"start_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"end_time":{"type":"string","nullable":true,"description":"24-hour `HH:MM`."},"registration_open_date":{"type":"string","format":"date-time","nullable":true},"registration_close_date":{"type":"string","format":"date-time","nullable":true},"order":{"type":"integer","nullable":true},"max_participants":{"type":"integer","nullable":true},"min_age":{"type":"integer","nullable":true},"max_age":{"type":"integer","nullable":true},"allow_race_day_registration":{"type":"boolean","nullable":true},"race_day_price_cents":{"type":"integer","nullable":true},"hidden":{"type":"boolean","nullable":true},"invite_only":{"type":"boolean","nullable":true},"requires_login":{"type":"boolean","description":"Whether athletes must be signed in to register for this sub-event."},"show_spots_remaining":{"type":"boolean","nullable":true},"multiple_registration":{"type":"boolean","nullable":true},"has_waitlist":{"type":"boolean","nullable":true},"require_applications":{"type":"boolean","description":"When true, every registrant enters the waitlist/application flow for\nthis sub-event regardless of remaining capacity. Surfaced to athletes\nas an application rather than a waitlist.\n"},"waitlist_auto_invite_enabled":{"type":"boolean","nullable":true},"waitlist_invite_response_window_hours":{"type":"integer","nullable":true},"waitlist_under_capacity_grace_period_minutes":{"type":"integer","nullable":true},"waitlist_invite_cutoff_at":{"type":"string","format":"date-time","nullable":true},"has_multiple_participants":{"type":"boolean","nullable":true},"multi_participant_count":{"type":"integer","nullable":true},"multi_participant_max_count":{"type":"integer","nullable":true},"allowed_gender_ids":{"type":"array","nullable":true,"description":"Array of `GenderIdentity` integer IDs that may register for this\nsub-event. `null` means all genders are allowed.\n","items":{"type":"integer"}},"registration_code_set":{"type":"boolean","description":"Whether a private registration code is configured."},"distance":{"type":"number","nullable":true,"description":"Sub-event distance expressed in `distance_display_unit` (e.g. 13.1\nwhen the unit is `miles`). This is the value to send back on a write.\n"},"distance_meters":{"type":"integer","nullable":true,"description":"Sub-event distance normalized to meters. This is the canonical,\nqueryable value; `distance_display_unit` records the unit it was\nentered in.\n"},"distance_display_unit":{"type":"string","nullable":true,"enum":["meters","kilometers","miles"],"description":"Display unit the organizer entered the distance in."},"formatted_distance":{"type":"string","nullable":true,"description":"Preformatted distance in the display unit, e.g. `\"13.1 mi\"`."},"prices":{"type":"array","items":{"$ref":"#/components/schemas/SubEventPrice"}}}},"SubEventPrice":{"type":"object","required":["id","price_cents","price_dollars","is_sliding_scale","close_date","description"],"properties":{"id":{"type":"integer","format":"int64"},"price_cents":{"type":"integer","description":"Tier price in the event's currency, in minor units (cents)."},"price_dollars":{"type":"number","format":"double","description":"Convenience copy of `price_cents` divided by 100."},"is_sliding_scale":{"type":"boolean"},"close_date":{"type":"string","format":"date-time","nullable":true,"description":"When this tier ends. Null on the final/highest tier."},"description":{"type":"string","nullable":true}}},"OAuthError":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable error code"},"error_description":{"type":"string","description":"Human-readable description of the error"}}},"Error":{"type":"object","description":"A generic error response","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message"}}},"ValidationError":{"type":"object","description":"A validation error response with a list of error messages","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"string"},"description":"List of validation error messages"}}}},"responses":{"Unauthorized":{"description":"Unauthorized - invalid or missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"Forbidden":{"description":"Forbidden - user is not an admin of this event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"SubEventNotFound":{"description":"Event or sub-event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/api/v1/events/{handle}/sub_events/{id}":{"patch":{"tags":["Sub-events"],"summary":"Update a sub-event","description":"Partially update a sub-event. Fields not present in the request are\nleft untouched. Sending an explicit `null` (or empty string for\nstrings) clears a value where the field is nullable. Pricing\ntiers — when supplied — completely replace the existing tiers.\n","operationId":"updateSubEvent","parameters":[{"$ref":"#/components/parameters/EventHandle"},{"$ref":"#/components/parameters/ResourceId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubEventRequest"}}}},"responses":{"200":{"description":"Sub-event updated","content":{"application/json":{"schema":{"type":"object","required":["sub_event"],"properties":{"sub_event":{"$ref":"#/components/schemas/SubEvent"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/SubEventNotFound"},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}}}}}}}
````
