> 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/course-maps.md).

# Course Maps

Attach Strava and Ride with GPS routes to an event as course maps. OAuth-gated: callers without a current Strava / RWG token receive a structured `oauth_required` error with a `connect_url`.

## GET /api/v1/events/{handle}/course\_maps

> List course maps attached to the event

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Course Maps","description":"Attach Strava and Ride with GPS routes to an event as course maps.\nOAuth-gated: callers without a current Strava / RWG token receive a\nstructured `oauth_required` error with a `connect_url`.\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":{"CourseMap":{"type":"object","required":["id","name","provider","provider_route_id","provider_created_at"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"provider":{"type":"string","enum":["strava","ride_with_gps","other"]},"provider_route_id":{"type":"string","description":"Numeric provider id, returned as a string to avoid JS number precision loss."},"provider_created_at":{"type":"string","format":"date-time","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}/course_maps":{"get":{"tags":["Course Maps"],"summary":"List course maps attached to the event","operationId":"listCourseMaps","parameters":[{"$ref":"#/components/parameters/EventHandle"}],"responses":{"200":{"description":"Course maps","content":{"application/json":{"schema":{"type":"object","required":["course_maps"],"properties":{"course_maps":{"type":"array","items":{"$ref":"#/components/schemas/CourseMap"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/EventNotFound"}}}}}}
````

## Attach a course map from Strava or Ride with GPS

> Attaches an existing route owned by the organizer's connected\
> Strava or RWG account. OAuth-gated; returns 422 \`oauth\_required\`\
> with a \`connect\_url\` if the corresponding integration isn't\
> connected. Strava routes additionally require the \`read\_all\`\
> scope; insufficient scope is surfaced as 422 \`insufficient\_scope\`.<br>

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Course Maps","description":"Attach Strava and Ride with GPS routes to an event as course maps.\nOAuth-gated: callers without a current Strava / RWG token receive a\nstructured `oauth_required` error with a `connect_url`.\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":{"CreateCourseMapRequest":{"type":"object","description":"For Strava routes pass `{source: \"strava\", strava_route_id}`. For\nRide with GPS pass `{source: \"ride_with_gps\", route_id}`.\n","required":["source"],"properties":{"source":{"type":"string","enum":["strava","ride_with_gps"]},"strava_route_id":{"type":"integer"},"route_id":{"type":"integer"}}},"CourseMap":{"type":"object","required":["id","name","provider","provider_route_id","provider_created_at"],"properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"provider":{"type":"string","enum":["strava","ride_with_gps","other"]},"provider_route_id":{"type":"string","description":"Numeric provider id, returned as a string to avoid JS number precision loss."},"provider_created_at":{"type":"string","format":"date-time","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"}}},"CourseMapOAuthError":{"type":"object","required":["error","provider","message"],"properties":{"error":{"type":"string","enum":["oauth_required","insufficient_scope"]},"provider":{"type":"string","enum":["strava","ride_with_gps"]},"message":{"type":"string"},"connect_url":{"type":"string"}}}},"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"}}}}}},"paths":{"/api/v1/events/{handle}/course_maps":{"post":{"tags":["Course Maps"],"summary":"Attach a course map from Strava or Ride with GPS","description":"Attaches an existing route owned by the organizer's connected\nStrava or RWG account. OAuth-gated; returns 422 `oauth_required`\nwith a `connect_url` if the corresponding integration isn't\nconnected. Strava routes additionally require the `read_all`\nscope; insufficient scope is surfaced as 422 `insufficient_scope`.\n","operationId":"createCourseMap","parameters":[{"$ref":"#/components/parameters/EventHandle"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCourseMapRequest"}}}},"responses":{"201":{"description":"Attached","content":{"application/json":{"schema":{"type":"object","required":["course_map"],"properties":{"course_map":{"$ref":"#/components/schemas/CourseMap"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Route not found in the athlete's account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"OAuth required, insufficient scope, or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CourseMapOAuthError"}}}}}}}}}
````

## DELETE /api/v1/events/{handle}/course\_maps/{id}

> Detach a course map from the event

````json
{"openapi":"3.1.0","info":{"title":"Movemint API","version":"1.0"},"tags":[{"name":"Course Maps","description":"Attach Strava and Ride with GPS routes to an event as course maps.\nOAuth-gated: callers without a current Strava / RWG token receive a\nstructured `oauth_required` error with a `connect_url`.\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"}}}},"EventNotFound":{"description":"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}/course_maps/{id}":{"delete":{"tags":["Course Maps"],"summary":"Detach a course map from the event","operationId":"deleteCourseMap","parameters":[{"$ref":"#/components/parameters/EventHandle"},{"$ref":"#/components/parameters/ResourceId"}],"responses":{"200":{"description":"Detached","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/EventNotFound"}}}}}}
````


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://movemint.gitbook.io/movemint-developer-docs/open-api-specification/core-resources/course-maps.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
