Raw schema
{
"type": "object",
"properties": {
"course_file": {
"description": "Inline/proxied GPX, FIT, CRSProf, or ZIP-with-one-GPX file object to import. Use content for text GPX/XML/JSON/CRSProf or base64 for FIT/ZIP/binary. Bare local filesystem paths and file:// URLs are rejected.",
"properties": {
"base64": {
"type": "string",
"description": "Base64-encoded file bytes for FIT or other binary files."
},
"content": {
"type": "string",
"description": "Inline text file content for GPX/XML/JSON/USRProf."
},
"file_name": {
"type": "string",
"description": "Original file name, e.g. course.gpx or runner.usrprof."
},
"url": {
"format": "uri",
"type": "string",
"description": "Fetchable HTTPS URL to file bytes. Do not use file:// or bare local paths. ZIP is accepted only when it contains exactly one GPX file."
},
"name": {
"type": "string",
"description": "Original file name, e.g. course.gpx or runner.usrprof."
},
"content_type": {
"type": "string",
"description": "MIME type for the file."
}
},
"type": "object",
"additionalProperties": false
},
"course": {
"additionalProperties": false,
"required": [],
"type": "object",
"properties": {
"import_options": {
"type": "object",
"additionalProperties": true
},
"waypoints": {
"additionalProperties": false,
"required": [
"mode"
],
"type": "object",
"properties": {
"source_ref": {
"type": "string",
"description": "Optional source reference for parsed waypoint rows."
},
"text": {
"type": "string",
"description": "Raw aid-station table text for best-effort table parsing."
},
"items": {
"type": "array",
"items": {
"additionalProperties": false,
"required": [
"name",
"distance"
],
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"start",
"finish",
"aid",
"checkpoint",
"water",
"crew",
"other"
]
},
"cutoff_kind": {
"type": "string",
"enum": [
"in",
"out",
"leave"
]
},
"distance": {
"type": "number",
"description": "Distance from start."
},
"name": {
"type": "string",
"description": "Waypoint, aid station, checkpoint, start, or finish name."
},
"resources": {
"type": "array",
"description": "Canonical aid/resources available here. Unsupported/free-text strings are ignored with warnings; preserve non-canonical details in note/source text.",
"items": {
"type": "string",
"enum": [
"water",
"water_source",
"drinks",
"fruit",
"food",
"toilet",
"medic",
"chrono",
"crew",
"pacer",
"car",
"bus",
"ambulance",
"shuttle",
"drop_bag",
"withdrawal",
"binoculars",
"hot_meal",
"tent",
"showers",
"changing_room",
"physiotherapy",
"rest_area",
"start_flag",
"finish_flag"
]
}
},
"cutoff": {
"type": "string",
"description": "Elapsed cutoff time HH:MM, if known."
},
"distance_unit": {
"type": "string",
"enum": [
"km",
"m",
"mi"
]
}
}
}
},
"table_url": {
"type": "string",
"description": "Public URL to an aid-station table for best-effort parsing; verify results. If official documents disagree or exact aid locations are not listed, ask the user to confirm rather than inventing missing aid stations."
},
"start_time": {
"type": "string",
"description": "Optional race start time used when parsing absolute cutoffs."
},
"mode": {
"enum": [
"structured",
"table"
],
"type": "string",
"description": "Use structured for reliable AI workflows."
},
"distance_unit": {
"type": "string",
"enum": [
"km",
"m",
"mi"
]
}
}
},
"crsprof_artifact_id": {
"type": "string",
"description": "Existing converted CRSProf artifact ID to submit after optional metadata/enrichment/segmentation."
},
"source": {
"properties": {
"artifact_id": {
"type": "string",
"description": "Existing CourseProfiler artifact ID, e.g. art_..."
},
"content": {
"type": "string",
"description": "Inline text file content for raw_file inputs, suitable for GPX/XML/JSON/USRProf."
},
"payload": {
"additionalProperties": true,
"type": "object",
"description": "Inline raw JSON payload for CRSProf/USRProf-compatible inputs."
},
"url": {
"format": "uri",
"type": "string",
"description": "Fetchable public URL to a GPX, FIT, CRSProf, USRProf, or evidence file. For course inputs, prefer official direct GPX/FIT/CRSProf URLs over generic race homepages, but stop and ask the user to download/upload when the host blocks server fetches (for example 403 from Wikiloc or other route hosts). Do not synthesize course geometry from roadbooks, checkpoint tables, or elevation profiles."
},
"file_name": {
"type": "string",
"description": "File name for inline raw_file content, e.g. course.gpx or runner.usrprof."
},
"content_type": {
"type": "string",
"description": "MIME type for inline raw_file content."
},
"base64": {
"type": "string",
"description": "Base64-encoded file bytes for raw_file inputs, suitable for FIT or other binary files."
},
"kind": {
"type": "string",
"enum": [
"url",
"artifact",
"raw_json",
"raw_file"
]
}
},
"required": [
"kind"
],
"type": "object",
"additionalProperties": true
},
"segments": {
"additionalProperties": false,
"required": [],
"type": "object",
"properties": {
"options": {
"additionalProperties": false,
"required": [],
"type": "object",
"properties": {
"instant_mode": {
"type": "boolean",
"description": "Use instant segmentation mode."
},
"slope_change_threshold": {
"type": "number",
"description": "Slope-change threshold percent."
},
"flexible_minimum_distance": {
"type": "boolean",
"description": "Allow flexible minimum-distance behavior."
},
"algorithm": {
"type": "string",
"description": "Segment partitioning algorithm, e.g. SLOPE_BASED."
},
"flat_grade": {
"type": "number",
"description": "Flat grade threshold percent."
},
"include_routes": {
"type": "boolean",
"description": "Include route geometry in generated CRSProf."
},
"flat_max_delta": {
"type": "number",
"description": "Maximum elevation delta for flat segments, meters."
},
"minimum_distance": {
"type": "number",
"description": "Minimum segment distance, meters."
},
"flexible_flat_max_delta": {
"type": "boolean",
"description": "Allow flexible flat max-delta behavior."
}
}
},
"mode": {
"type": "string",
"enum": [
"generate",
"skip"
]
}
}
}
}
},
"metadata": {
"additionalProperties": false,
"required": [],
"type": "object",
"properties": {
"event": {
"description": "Important catalog metadata collected from official sources. Populate known fields such as name/event_name, course, year/date, time (race start time), location/city/region/country, distance, elevation_gain, organizer/series, website, official_source_url, types, competitions, and links. metadata.event.name is the main event name and metadata.event.course is the specific course name (for example name='Speedgoat Mountain Races', course='50K'); do not put distance/elevation stats in the course name (bad: 'Skyrace — 32 km, +2400 m'). metadata.event.location must not include country because metadata.event.country is separate. Add metadata.event.types tags when officially applicable (for example race/trail/ultra), and add metadata.event.competitions when the race belongs to a circuit/series/championship, e.g. Golden Trail World Series (GTWS). Do not invent unknown values; omit or leave null when not confirmed. For event-level links, use links with type/url/tooltip entries for General Information (info), Registration (registration), Rules/Regulations (rules), Schedule/Program (schedule), Course (course), Cut-off times (cutoff), Parking (parking), Bib pick-up (bib_pickup), Wardrobe/drop bag (wardrobe), Results (results), and Contact (contact).",
"properties": {
"distance_unit": {
"type": "string",
"enum": [
"km",
"m",
"mi"
]
},
"country": {
"type": "string",
"description": "Event country."
},
"types": {
"type": "array",
"description": "Catalog tags/types that apply from official context, e.g. race, trail, ultra, skyrunning. Add obvious tags where they apply; do not invent niche tags.",
"items": {
"type": "string"
}
},
"region": {
"type": "string",
"description": "Event region/state/province, if listed separately."
},
"links": {
"type": "array",
"description": "Structured event-level links displayed in the catalog UI. Always add official links when available instead of only listing them in source_urls. Use type values such as info, registration, rules, schedule, course, cutoff, parking, bib_pickup, wardrobe, results, contact.",
"items": {
"additionalProperties": false,
"required": [
"type",
"url"
],
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "Official URL for this event link."
},
"type": {
"enum": [
"info",
"registration",
"rules",
"schedule",
"course",
"start_line",
"parking",
"bib_pickup",
"wardrobe",
"cutoff",
"results",
"contact"
],
"type": "string",
"description": "Event link kind. Use info for General Information, registration for Registration, rules for Rules/Regulations, schedule for Schedule/Program, course for route/course page, cutoff for cut-off information."
},
"tooltip": {
"type": "string",
"description": "Optional human-readable label, e.g. General Information, Registration, Rules, Schedule, Course, Parking."
}
}
}
},
"website": {
"type": "string",
"description": "Official race/course page URL."
},
"city": {
"type": "string",
"description": "Event city, if listed separately."
},
"distance": {
"type": "number",
"description": "Official course distance."
},
"course": {
"type": "string",
"description": "specific course/distance/variant name only. Do not include distance/elevation stats such as 'Skyrace — 32 km, +2400 m'; put those in dedicated distance/elevation fields. Example: 50K."
},
"official_source_url": {
"type": "string",
"description": "Primary official source URL used for event metadata."
},
"year": {
"type": "integer",
"description": "Race year."
},
"location": {
"type": "string",
"description": "Event location/city/region only. Do not include country here; use metadata.event.country for country."
},
"event_name": {
"type": "string",
"description": "Alternative main event/race name field; do not include the course/distance variant unless official."
},
"organizer": {
"additionalProperties": true,
"type": "object",
"description": "Event organizer/promoter, preferably {name,url}. Do not use this for competition/series membership unless the series is also the organizer."
},
"elevation_gain_unit": {
"type": "string",
"enum": [
"m",
"ft"
]
},
"series": {
"type": "string",
"description": "Race series name, if applicable; prefer structured metadata.event.competitions for catalog submissions."
},
"time": {
"type": "string",
"description": "Race start time from official sources, preferably HH:MM local time. Include this when available; it is distinct from date."
},
"name": {
"type": "string",
"description": "main event/race name, not the course/distance variant. Example: Speedgoat Mountain Races."
},
"elevation_gain": {
"type": "number",
"description": "Official elevation gain, meters unless elevation_gain_unit is provided."
},
"competitions": {
"type": "array",
"description": "Race series/circuit/championship memberships, separate from organizer. Example: [{name: 'Golden Trail World Series', url: 'https://www.goldentrailseries.com/'}] for GTWS races.",
"items": {
"type": "object",
"additionalProperties": true
}
},
"date": {
"type": "string",
"description": "Race date, preferably YYYY-MM-DD."
}
},
"type": "object",
"additionalProperties": true
},
"source_urls": {
"type": "array",
"description": "Official URLs used for route geometry, race page, aid chart, regulations, or other metadata evidence. This is provenance only; event links shown in the catalog UI must also be added to metadata.event.links with type/url/tooltip.",
"items": {
"type": "string"
}
}
}
},
"race_name": {
"type": "string",
"description": "Race/course name to submit. Assistants should search the catalog and official web sources before calling submit_course, then populate metadata.event from official sources, including metadata.event.time and metadata.event.links when available."
},
"submitter": {
"additionalProperties": false,
"required": [],
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Optional submitter name."
},
"email": {
"type": "string",
"description": "Optional submitter email."
}
}
},
"original_file_name": {
"type": "string",
"description": "Optional original route/profile file name for review metadata."
}
},
"required": [
"course"
],
"additionalProperties": false
}