{
	"$schema": "http://json-schema.org/draft-07/schema#",
	"$id": "https://2timer.app/omx/schemas/results-document-v1.schema.json",
	"$comment": "Generated from meet-document-v1.schema.json by npm run sync:omx. A strict writer schema: only values this version defines, every field in its stage, and date-times with seconds. An extra field never fails (OMX-R129). Readers validate with the lenient meet-document-v1.",
	"title": "Open Meet Exchange — Results Document v1 (strict)",
	"description": "A meet document as Meet Operations hands it to a Publisher: what happened. It carries omx.kind results, omx.update, omx.updated_at, and meet.origin; one entry per athlete or relay per round; and no destinations, athlete contact, birth date, chip, or notes.",
	"type": "object",
	"additionalProperties": true,
	"required": ["omx", "meet", "events", "teams", "athletes", "entries"],
	"properties": {
		"$schema": {
			"type": "string",
			"description": "Optional URL of this schema, for editors."
		},
		"omx": {
			"$ref": "#/definitions/header"
		},
		"meet": {
			"$ref": "#/definitions/meet"
		},
		"divisions": {
			"type": "array",
			"description": "Competition groupings that events belong to (Varsity, Masters 40–44, U12).",
			"items": {
				"$ref": "#/definitions/division"
			}
		},
		"groups": {
			"type": "array",
			"description": "Award groups within a race: age groups in a road race, JV within a varsity cross country race. Each names an event (or all events), a gender, and an age or grade span.",
			"items": {
				"$ref": "#/definitions/group"
			}
		},
		"waves": {
			"type": "array",
			"description": "Start waves in road and trail races.",
			"items": {
				"$ref": "#/definitions/wave"
			}
		},
		"events": {
			"type": "array",
			"description": "What is contested, in running order. A results document adds `rounds`, and lists the component events of a multi-event.",
			"items": {
				"$ref": "#/definitions/event"
			}
		},
		"teams": {
			"type": "array",
			"items": {
				"$ref": "#/definitions/team"
			}
		},
		"athletes": {
			"type": "array",
			"items": {
				"$ref": "#/definitions/athlete"
			}
		},
		"entries": {
			"type": "array",
			"description": "In a registration document, one entry per athlete or relay per event: who entered. In a results document, one entry per athlete or relay per round, with `round` required: what happened. A scratch in a registration document is an entry with `status: \"scr\"`, never a missing entry.",
			"items": {
				"$ref": "#/definitions/entry"
			}
		},
		"team_scores": {
			"type": "array",
			"description": "Team standings. Only in a results document, written by Meet Operations.",
			"items": {
				"$ref": "#/definitions/teamScores"
			}
		}
	},
	"definitions": {
		"id": {
			"type": "string",
			"description": "Opaque identifier chosen by the product that wrote the document. Stable for the life of the meet. A reader never parses it.",
			"minLength": 1,
			"maxLength": 128
		},
		"externalIds": {
			"type": "object",
			"description": "This record's ids in other products, keyed by system id (a writer's own `generator.id`, such as `examplereg`; for a system that writes no OMX document, the key the spec lists, such as `anet`), one per system. Only the meet, events, teams, and athletes carry them; an entry never does. A writer never lists itself: its own id is `id`. In a results document, a record that came from Registration carries Registration's id here under Registration's system id (`meet.origin.id`), and Meet Operations writes back every id it received, unchanged, whether or not it knows the system. A record Meet Operations created carries no Registration id.",
			"additionalProperties": {
				"type": "string",
				"minLength": 1,
				"maxLength": 128
			}
		},
		"laterValue": {
			"not": {},
			"description": "A value this version does not define, which a writer of this version never sends."
		},
		"dateTime": {
			"type": "string",
			"description": "RFC 3339 date-time with seconds and a UTC offset, e.g. 2026-10-03T09:00:00-04:00. A writer always includes seconds (the strict writer schemas require them); a reader also accepts a date-time without seconds.",
			"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?([Zz]|[+-]\\d{2}:\\d{2})$"
		},
		"date": {
			"type": "string",
			"description": "ISO 8601 calendar date, e.g. 2026-10-03.",
			"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
		},
		"athleteGender": {
			"type": "string",
			"description": "An athlete's gender: `M` male, `F` female, `X` non-binary. Closed. Absent when the athlete did not state one, which road registration commonly allows; a reader that does not tell the two apart may treat an absent gender as `X`.",
			"enum": ["M", "F", "X"]
		},
		"eventGender": {
			"type": "string",
			"description": "Who a contest is for, with the same letters as an athlete's gender: `M` men or boys, `F` women or girls, `X` non-binary athletes, `C` everyone (mixed, combined, or co-ed), including a relay whose team may mix genders; each athlete in a `C` contest is also placed within their own gender. `C` is never an athlete's gender. Closed. Registration decides who may enter; Meet Operations takes an entry as given.",
			"enum": ["M", "F", "X", "C"]
		},
		"sport": {
			"type": "string",
			"description": "The sport. Indoor and outdoor track are separate because their event catalogs differ. Event codes are defined per sport. Open: a later minor adds sports. A Meet Operations product that does not run a sport refuses the document and names the sport; a Publisher shows the meet's events by their names and codes.",
			"anyOf": [
				{
					"enum": ["xc", "tf-indoor", "tf-outdoor", "run"]
				},
				{
					"$ref": "#/definitions/laterValue"
				}
			]
		},
		"markUnit": {
			"type": "string",
			"description": "`ms` milliseconds, `mm` millimetres, `in` inches, `pt` points: the unit the event's code ranks by. Open: a reader that meets a unit it does not know shows the mark's `display` and never compares or sorts on it.",
			"anyOf": [
				{
					"enum": ["ms", "mm", "in", "pt"]
				},
				{
					"$ref": "#/definitions/laterValue"
				}
			]
		},
		"mark": {
			"type": "object",
			"description": "A seed or performance. `value` is a number in the unit the writer measured in, so nothing is converted before the reader sees it: ms for times, mm or in for distances and heights, pt for points, as the event's code ranks. ms, mm, and pt are integers; in is decimal inches to at most two places (16-06.25 is 198.25). Compare on `value`; print `display`, the writer's own formatting, which is never parsed.",
			"required": ["value", "unit"],
			"properties": {
				"value": {
					"type": "number",
					"minimum": 0
				},
				"unit": {
					"$ref": "#/definitions/markUnit"
				},
				"display": {
					"type": "string"
				},
				"source": {
					"type": "string",
					"description": "On a seed: where the mark came from, e.g. `season_best`, `coach_entered`, `previous_meet`. Free text; shown to the timer, never interpreted."
				},
				"achieved_on": {
					"$ref": "#/definitions/date"
				}
			},
			"if": {
				"properties": {
					"unit": {
						"enum": ["ms", "mm", "pt"]
					}
				}
			},
			"then": {
				"properties": {
					"value": {
						"type": "integer"
					}
				}
			}
		},
		"split": {
			"type": "object",
			"description": "One intermediate time: where it was taken (a marker, a relay leg, or both) and the elapsed time there.",
			"required": ["time_ms"],
			"properties": {
				"marker_id": {
					"$ref": "#/definitions/id",
					"description": "Where the split was taken, by its `id` in the event's `markers`."
				},
				"leg": {
					"type": "integer",
					"minimum": 1,
					"description": "For a relay, the leg this split ends: `1` is the first leg."
				},
				"time_ms": {
					"type": "integer",
					"minimum": 0,
					"description": "Elapsed milliseconds from the same start as `result`: the gun for the athlete's race or wave. A relay leg's split is the running clock when that leg finished. A Publisher subtracts two splits to show one stretch."
				}
			},
			"anyOf": [
				{
					"required": ["marker_id"]
				},
				{
					"required": ["leg"]
				}
			]
		},
		"header": {
			"type": "object",
			"required": ["version", "kind", "generator", "update", "updated_at"],
			"properties": {
				"version": {
					"type": "string",
					"description": "Format version as MAJOR.MINOR. A reader accepts any minor within a major it implements and ignores fields it does not know; a major it does not implement is refused with a message naming both versions. A draft document carries its draft number (`0.1` to `0.9`), which a 1.x reader refuses; a reader checks the version before validating.",
					"pattern": "^(0|1)\\.\\d+$"
				},
				"kind": {
					"type": "string",
					"description": "Which handoff this is. `registration`: written by Registration, who entered. `results`: written by Meet Operations, what happened. Closed: a reader refuses a document whose kind it does not know, or that is not the kind it reads (Meet Operations reads registration documents; a Publisher reads results documents).",
					"enum": ["results"]
				},
				"update": {
					"type": "string",
					"description": "Results documents only: what the document covers. `full`: the whole meet as it stands; the Publisher replaces everything it holds for the meet. `partial`: only the rounds it carries, each whole; the Publisher replaces those rounds and the team scores the document carries, adds or updates the meet, divisions, groups, waves, events, teams, and athletes it carries by `id`, and changes nothing else. A Publisher refuses an `update` it does not know with 422 and never reads it as `full`.",
					"anyOf": [
						{
							"enum": ["full", "partial"]
						},
						{
							"$ref": "#/definitions/laterValue"
						}
					]
				},
				"updated_at": {
					"type": "string",
					"description": "Results documents only, required there: when the meet's data last changed, not when this copy was sent. Orders documents: a Publisher applies a newer one, treats an equal one as a no-op, and refuses an older one with 409, whatever its `update`, comparing instants rather than text. Written to at least the millisecond, with a UTC offset; a reader accepts one with less. Any change moves it forward, including a deletion; it never goes backwards.",
					"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3,9}([Zz]|[+-]\\d{2}:\\d{2})$"
				},
				"generator": {
					"type": "object",
					"required": ["id", "name"],
					"properties": {
						"id": {
							"type": "string",
							"pattern": "^[a-z0-9_]{1,32}$",
							"description": "The writer's system id: lowercase letters, digits, and `_`, at most 32, any name the writer picks, chosen once and never changed, such as `2t` for 2Timer; nobody assigns it. Other documents carry this product's ids in `external_ids` under it."
						},
						"name": {
							"type": "string",
							"description": "The product's name as people know it, e.g. ExampleRegistration or 2Timer."
						},
						"version": {
							"type": "string",
							"description": "The product's own version, e.g. 3.4."
						}
					},
					"description": "The product that wrote this copy: Registration's product in a registration document, Meet Operations' product in a results document."
				}
			},
			"description": "About this copy of the document: the format version, its kind, which product wrote it, and, in a results document, what it covers and when the meet last changed."
		},
		"meet": {
			"type": "object",
			"required": ["id", "name", "sport", "start_date", "origin"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"external_ids": {
					"$ref": "#/definitions/externalIds"
				},
				"name": {
					"type": "string",
					"minLength": 1
				},
				"sport": {
					"$ref": "#/definitions/sport"
				},
				"start_date": {
					"$ref": "#/definitions/date"
				},
				"end_date": {
					"$ref": "#/definitions/date"
				},
				"time_zone": {
					"type": "string",
					"description": "IANA time zone, e.g. America/New_York: the zone the meet's dates and schedule are in. Optional. Without it, dates are the meet's own local calendar dates as written, and each date-time is read by its own UTC offset."
				},
				"venue": {
					"type": "object",
					"properties": {
						"name": {
							"type": "string"
						},
						"address": {
							"type": "string"
						},
						"city": {
							"type": "string"
						},
						"region": {
							"type": "string",
							"description": "State, province, or county."
						},
						"postal_code": {
							"type": "string"
						},
						"country": {
							"type": "string",
							"description": "ISO 3166-1 alpha-2, e.g. US.",
							"pattern": "^[A-Z]{2}$"
						},
						"latitude": {
							"type": "number",
							"minimum": -90,
							"maximum": 90
						},
						"longitude": {
							"type": "number",
							"minimum": -180,
							"maximum": 180
						}
					}
				},
				"track": {
					"type": "object",
					"description": "Results documents only: the track the meet was run on, written by Meet Operations. Track and field only.",
					"properties": {
						"length_m": {
							"type": "number",
							"exclusiveMinimum": 0,
							"description": "Lap length in metres. A 160-yard track is `146.304`."
						},
						"lane_count": {
							"type": "integer",
							"minimum": 1
						},
						"straight_lane_count": {
							"type": "integer",
							"minimum": 1
						},
						"shape": {
							"type": "string",
							"description": "Open. A reader treats a value it does not know as absent.",
							"anyOf": [
								{
									"enum": ["oval_flat", "oval_banked"]
								},
								{
									"$ref": "#/definitions/laterValue"
								}
							]
						}
					}
				},
				"origin": {
					"type": "object",
					"description": "Results documents only: the product this meet started in. A meet's entries come from one Registration product. Registration's system id and name when the meet was built from a registration document, so records from Registration carry their ids in `external_ids` under `origin.id`; Meet Operations' own when the timer built the meet, so no record carries a Registration id.",
					"required": ["id", "name"],
					"properties": {
						"id": {
							"type": "string",
							"pattern": "^[a-z0-9_]{1,32}$",
							"description": "That product's system id: its `omx.generator.id`."
						},
						"name": {
							"type": "string",
							"description": "That product's name: its `omx.generator.name`, e.g. ExampleRegistration."
						}
					}
				}
			},
			"allOf": [
				{
					"not": {
						"required": ["notes"]
					}
				}
			]
		},
		"division": {
			"type": "object",
			"required": ["id", "name", "sequence"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"name": {
					"type": "string"
				},
				"short_name": {
					"type": "string"
				},
				"sequence": {
					"type": "integer",
					"minimum": 1
				},
				"gender_names": {
					"type": "object",
					"description": "What this division calls each gender's contest, keyed by event gender, e.g. {\"M\": \"Boys\", \"F\": \"Girls\", \"C\": \"Mixed\"}.",
					"propertyNames": {
						"enum": ["M", "F", "X", "C"]
					},
					"additionalProperties": {
						"type": "string"
					}
				}
			}
		},
		"span": {
			"type": "object",
			"properties": {
				"min": {
					"type": "integer",
					"minimum": 0
				},
				"max": {
					"type": "integer",
					"minimum": 0
				}
			}
		},
		"gradeSpan": {
			"type": "object",
			"description": "Grades as Registration labels them (\"9\", \"12\", \"K\").",
			"properties": {
				"min": {
					"type": "string"
				},
				"max": {
					"type": "string"
				}
			}
		},
		"group": {
			"type": "object",
			"required": ["id", "name", "gender"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"name": {
					"type": "string"
				},
				"event_id": {
					"$ref": "#/definitions/id",
					"description": "The race this group awards within. Absent means every event."
				},
				"gender": {
					"$ref": "#/definitions/eventGender",
					"description": "Who the group is for. `C` groups everyone in the age or grade span; `X` is a non-binary group."
				},
				"age": {
					"$ref": "#/definitions/span"
				},
				"grade": {
					"$ref": "#/definitions/gradeSpan"
				},
				"award_count": {
					"type": "integer",
					"minimum": 0
				}
			},
			"description": "An award group within a race: an age group in a road race, JV within a varsity cross country race. Age and grade spans are inclusive at both ends; an age span is matched against the athlete's `age`."
		},
		"event": {
			"type": "object",
			"required": ["id", "name", "code", "gender"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"external_ids": {
					"$ref": "#/definitions/externalIds"
				},
				"number": {
					"type": "integer",
					"minimum": 1,
					"description": "Event number if one is assigned. Otherwise Meet Operations numbers in array order."
				},
				"name": {
					"type": "string"
				},
				"code": {
					"$ref": "#/definitions/eventCode"
				},
				"division_id": {
					"$ref": "#/definitions/id"
				},
				"gender": {
					"$ref": "#/definitions/eventGender"
				},
				"hurdle_height_mm": {
					"type": "integer",
					"minimum": 0,
					"description": "Registration may suggest it; a results document carries the height used."
				},
				"implement_weight_g": {
					"type": "integer",
					"minimum": 0,
					"description": "Registration may suggest it; a results document carries the weight used."
				},
				"multi_event_id": {
					"$ref": "#/definitions/id",
					"description": "Results documents only: for a component of a multi-event (the 100 m of a decathlon), the id of the multi-event it belongs to. Meet Operations builds the component events; Registration sends the multi-event alone."
				},
				"adaptive": {
					"type": "object",
					"description": "Marks an adaptive or para event: an event of the same code contested in an adaptive form. An adaptive event is a different event from the standard one with the same code; a reader that cannot hold adaptive events tells the operator and never merges one into the standard event.",
					"required": ["mode"],
					"properties": {
						"mode": {
							"type": "string",
							"description": "`wheelchair` a wheelchair race, `seated` a seated throw, `guided` run with a guide, `ambulatory` an adaptive event contested standing or running without a chair or guide. Open: a reader that does not know the value shows the event as adaptive with no mode.",
							"anyOf": [
								{
									"enum": ["wheelchair", "seated", "guided", "ambulatory"]
								},
								{
									"$ref": "#/definitions/laterValue"
								}
							]
						}
					}
				},
				"markers": {
					"type": "array",
					"description": "Results documents only: the timing points on the course or track where splits are taken, in course order. An entry's `splits` name them by `id`. A relay's leg splits need no marker.",
					"items": {
						"type": "object",
						"required": ["id", "name"],
						"properties": {
							"id": {
								"$ref": "#/definitions/id"
							},
							"name": {
								"type": "string",
								"description": "How the point is named on results: `1 Mile`, `2K`, `Swim`, `T1`."
							}
						}
					}
				},
				"rounds": {
					"type": "array",
					"description": "Results documents only: the rounds of this event, written by Meet Operations. Entries point at a round by number.",
					"items": {
						"$ref": "#/definitions/round"
					}
				}
			},
			"allOf": [
				{
					"not": {
						"required": ["notes"]
					}
				}
			]
		},
		"team": {
			"type": "object",
			"required": ["id", "code", "name"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"external_ids": {
					"$ref": "#/definitions/externalIds"
				},
				"code": {
					"type": "string",
					"description": "Short display code, unique within the document (`LHS`, `NIKE`), at most 16 characters in a written document. A writer that holds a longer code writes a shortened one of its own, still unique; it never holds back the meet for it. An athlete with no team leaves out `team_id`; a team listed by name for unattached athletes sets `unattached`.",
					"minLength": 1,
					"maxLength": 16
				},
				"name": {
					"type": "string"
				},
				"city": {
					"type": "string"
				},
				"region": {
					"type": "string"
				},
				"country": {
					"type": "string",
					"pattern": "^[A-Z]{2}$"
				},
				"unattached": {
					"type": "boolean",
					"default": false,
					"description": "A team listed by name, such as Unattached, whose athletes compete for no team: they carry no points and take no scoring position."
				}
			}
		},
		"athlete": {
			"type": "object",
			"required": ["id", "last_name"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id",
					"description": "Stable within the meet."
				},
				"external_ids": {
					"$ref": "#/definitions/externalIds"
				},
				"first_name": {
					"type": "string",
					"description": "Given name. Absent for an athlete with one name."
				},
				"middle_name": {
					"type": "string"
				},
				"last_name": {
					"type": "string",
					"description": "Family name, or the athlete's only name when they have one."
				},
				"gender": {
					"$ref": "#/definitions/athleteGender"
				},
				"age": {
					"type": "integer",
					"minimum": 0,
					"description": "In a registration document, the age Registration computed for this meet; an athlete carries `age` or `birth_date`, never both. In a results document, the age Meet Operations placed the athlete by, whether Registration sent an age or a birth date."
				},
				"grade": {
					"type": "string"
				},
				"team_id": {
					"$ref": "#/definitions/id",
					"description": "The athlete's team. An athlete with no team_id competes for no team: it carries no points and takes no scoring position."
				},
				"bib": {
					"type": "string",
					"description": "The athlete's bib for the meet. Registration may assign it, or leave it to the timer. In a results document it is the bib the athlete raced under. A runner with two bibs in one meet is two athletes."
				},
				"city": {
					"type": "string"
				},
				"region": {
					"type": "string"
				},
				"country": {
					"type": "string",
					"description": "ISO 3166-1 alpha-2 country code, upper case (`US`, `CA`).",
					"pattern": "^[A-Z]{2}$"
				},
				"exhibition": {
					"type": "boolean",
					"default": false,
					"description": "Exhibition, non-scoring athlete. Places and wins awards normally; never scores, never displaces, never takes a scoring slot, in any event the athlete enters. Separate from the team's `unattached` flag."
				}
			},
			"not": {
				"required": ["age", "birth_date"]
			},
			"allOf": [
				{
					"not": {
						"required": ["email"]
					}
				},
				{
					"not": {
						"required": ["phone"]
					}
				},
				{
					"not": {
						"required": ["notes"]
					}
				},
				{
					"not": {
						"required": ["birth_date"]
					}
				},
				{
					"not": {
						"required": ["chip"]
					}
				}
			]
		},
		"entryStatus": {
			"type": "string",
			"description": "Where this entry stands. Closed. A registration entry may carry one: `e` entered (confirmed or not), `scr` scratched, or `wait` wait list; a registration entry with none is `e`. A results entry carries exactly one of `status` and `overall_place`: a place means it placed, and otherwise its status is `e` on a heat sheet, `s` in the round with nothing to place yet, or where it ended without a place: `dnf` did not finish (a race, or a multi-event the athlete abandoned), `dns` did not start, `dq` disqualified, `fs` false start (timed track only), `nr` no result. Which a results entry may be depends on its round's status. `NT`, `NM`, and `NH` are NOT statuses: they are how `nr` prints (NT for a race, NM for a throw or horizontal jump, NH for a vertical jump), never `NR`, except in an event whose code the reader does not know. Only a placed entry and a `dq` carry a `result`; a `dq` keeps its recorded result and holds no place.",
			"enum": ["e", "scr", "wait", "s", "dnf", "dns", "dq", "fs", "nr"]
		},
		"entry": {
			"type": "object",
			"required": ["id", "event_id", "round"],
			"oneOf": [
				{
					"required": ["status"]
				},
				{
					"required": ["overall_place"]
				}
			],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"event_id": {
					"$ref": "#/definitions/id"
				},
				"athlete_id": {
					"$ref": "#/definitions/id",
					"description": "Individual entries. Exactly one of `athlete_id` or `relay`. In a registration document, athlete + event is unique among individual entries."
				},
				"relay": {
					"type": "object",
					"description": "Relay entries. Team + letter + event is unique among the relay entries of a registration document.",
					"required": ["team_id", "letter"],
					"properties": {
						"team_id": {
							"$ref": "#/definitions/id"
						},
						"letter": {
							"type": "string",
							"description": "The team's squad in this event: one upper-case letter, A for its first.",
							"pattern": "^[A-Z]$"
						},
						"legs": {
							"type": "array",
							"description": "Athlete ids in running order. May be shorter than the event's legs, may be empty, may name alternates after the running legs.",
							"items": {
								"$ref": "#/definitions/id"
							}
						}
					}
				},
				"seed": {
					"$ref": "#/definitions/mark"
				},
				"status": {
					"type": "string",
					"enum": ["e", "s", "dnf", "dns", "dq", "fs", "nr"],
					"description": "e on a heat sheet, s in the round with nothing to place yet, or where it ended without a place: dnf, dns, dq, fs, nr. A placed entry carries overall_place instead. Which a round may hold depends on its status."
				},
				"wave_id": {
					"$ref": "#/definitions/id",
					"description": "The start wave this entry runs in, by its `id` in `waves`. A wave runner's `result` is timed from the wave's own gun."
				},
				"round": {
					"type": "integer",
					"minimum": 1,
					"description": "Results documents only, required there: the round of the event this entry is in. Round-level state lives in `events[].rounds`. An athlete who competed in two rounds appears as two entries."
				},
				"heat": {
					"type": "integer",
					"minimum": 1,
					"description": "Heat or flight number."
				},
				"lane": {
					"type": "integer",
					"minimum": 1,
					"description": "Lane or position. Omitted where the event does not use lanes."
				},
				"result": {
					"allOf": [
						{
							"$ref": "#/definitions/mark"
						}
					],
					"description": "The recorded time or mark. For a timed event, the gun time: from the start signal for the athlete's race or wave, however the finish was captured. `value` is the stored value: times store to thousandths even where an event shows hundredths, and two results tie only when equal at stored value. Absent on a finisher with no recorded value."
				},
				"net_result": {
					"allOf": [
						{
							"$ref": "#/definitions/mark"
						}
					],
					"description": "Net time: from the moment the athlete crossed the start line to the finish, where a start mat recorded it. Never a substitute for `result`, which stays the gun time. The round's `place_by` says which of the two decided places."
				},
				"overall_place": {
					"type": "integer",
					"minimum": 1,
					"description": "Place across the whole round; on the round marked `final`, that is the event's place. A results entry carries exactly one of `overall_place` and `status`: a placed entry has no status. In a `started` round it is the place so far, which may still move. Two entries in one round with the same place are tied."
				},
				"heat_place": {
					"type": "integer",
					"minimum": 1,
					"description": "Place within the heat."
				},
				"gender_place": {
					"type": "integer",
					"minimum": 1,
					"description": "Place among athletes of the same gender, by the same clock as `overall_place`."
				},
				"group_places": {
					"type": "array",
					"description": "Places within the award groups the entry placed in.",
					"items": {
						"type": "object",
						"required": ["group_id", "place"],
						"properties": {
							"group_id": {
								"$ref": "#/definitions/id",
								"description": "The award group, by its `id` in `groups`."
							},
							"place": {
								"type": "integer",
								"minimum": 1
							}
						}
					}
				},
				"qualified": {
					"type": "string",
					"description": "The letter the results print after this entry's result in a round before the event's last, as it advanced: `Q` by place, `q` by time or mark, `qD` won a draw for the last spot, `qR` advanced by the referee, `qJ` advanced by the Jury of Appeal (World Athletics CR 25.4). A field qualifier is `q`. Absent on a final and on any result that prints no letter. Open: a reader shows a value it does not know as written.",
					"anyOf": [
						{
							"enum": ["Q", "q", "qD", "qR", "qJ"]
						},
						{
							"$ref": "#/definitions/laterValue"
						}
					]
				},
				"flags": {
					"type": "array",
					"description": "The timer's own flags on this result, in the order typed, as typed: a record (`MR`), a best (`PB`, `SB`), a standard met, a state qualifier at a regional (`Q`). Printed after the result and its `qualified`. Never a qualifier letter in a round before the event's last. Absent when there are none, which does not mean the result is not a record.",
					"items": {
						"type": "string",
						"minLength": 1
					}
				},
				"wind_mps": {
					"type": "number",
					"description": "For a field result only: the wind in metres per second for the mark that counted. A race's wind is on its heat (`rounds[].heats[].wind_mps`)."
				},
				"reaction_time_ms": {
					"type": "integer",
					"minimum": 0,
					"description": "Reaction time from the start signal, in milliseconds, where the start was monitored."
				},
				"points": {
					"type": "number",
					"description": "Team-scoring value, whether or not it counted: the track points earned, or the cross country scoring position. One value per entry: every team score block that lists the entry uses it. The team standing's `role` says whether it counted. Absent for a runner on an incomplete or unattached team."
				},
				"multi_points": {
					"type": "number",
					"description": "On a component entry of a multi-event: the points that component earned. A multi-event entry's total is its `result`, in `pt`."
				},
				"splits": {
					"type": "array",
					"description": "Intermediate times, in the order they were taken.",
					"items": {
						"$ref": "#/definitions/split"
					}
				},
				"field_series": {
					"type": "array",
					"description": "A field-event series in order. For a horizontal jump or throw, each attempt is one jump or throw. For a vertical jump, each attempt is one try at a bar height.",
					"items": {
						"type": "object",
						"properties": {
							"order": {
								"type": "integer",
								"minimum": 1
							},
							"mark": {
								"$ref": "#/definitions/mark",
								"description": "For a horizontal jump or throw, the measured mark, present when `outcome` is `o`. For a vertical jump, the bar height attempted, present on every attempt so a miss says what was missed."
							},
							"outcome": {
								"type": "string",
								"description": "`o` a valid attempt (a measured mark, or a height cleared), `x` a foul or miss, `-` a pass, `r` retired from the competition. Open: a reader treats a value it does not know as an attempt with no valid mark.",
								"anyOf": [
									{
										"enum": ["o", "x", "-", "r"]
									},
									{
										"$ref": "#/definitions/laterValue"
									}
								]
							},
							"wind_mps": {
								"type": "number",
								"description": "Wind for this attempt in metres per second, where the event records one per attempt."
							}
						},
						"required": ["order", "outcome"]
					}
				},
				"official_note": {
					"type": "string",
					"description": "A note from the officials about this result, published with it: the rule a disqualification was under, a jump-off, a protest outcome."
				}
			},
			"description": "In a registration document: one athlete or relay entered in one event, with its seed and status, and no result fields. In a results document: one athlete or relay in one round of one event, with `round` required. A prelim and a final are two entries, each with its own `id`. No entry carries `external_ids`: a Publisher joins an entry to Registration through its athlete and event (a relay's team, letter, and event).",
			"allOf": [
				{
					"not": {
						"required": ["group_id"]
					}
				}
			]
		},
		"publishDestination": {
			"type": "object",
			"description": "One Publisher Meet Operations hands the results to. The credential here is separate from the document URL's; holding the read link never grants the right to write.",
			"required": ["id", "url", "token"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id",
					"description": "Identifier for this destination, unique within the document and stable for the life of the meet."
				},
				"label": {
					"type": "string",
					"description": "Human name for this destination, shown to the timer when they are asked to approve it. Strongly recommended: without one the timer is asked to trust a bare URL."
				},
				"url": {
					"type": "string",
					"pattern": "^https://",
					"description": "Where Meet Operations POSTs each results document."
				},
				"token": {
					"type": "string",
					"description": "Sent as `Authorization: Bearer <token>` on every handoff. Never placed in a query string. Issued by whoever runs this destination, with at least 128 bits from a cryptographically secure generator (22 or more base62 characters; 32 recommended). A readable prefix is allowed and does not count toward the 128 bits. The Publisher decides how long it works and answers 410 once it stops.",
					"minLength": 22
				},
				"deliver": {
					"type": "string",
					"description": "How often this destination wants results. `final` (the default): `full` documents once every round is official or cancelled, and again for each correction. `progressive`: a first `full` document, then `partial` ones as each round is seeded, goes official, or changes. `live`: everything `progressive` gets, plus a `partial` document every few seconds while a round runs. Meet Operations may always send `full` instead of `partial`. Open: a value Meet Operations does not know is read as `final`.",
					"anyOf": [
						{
							"enum": ["final", "progressive", "live"]
						},
						{
							"$ref": "#/definitions/laterValue"
						}
					],
					"default": "final"
				},
				"content": {
					"type": "array",
					"description": "What this destination wants. `results` (the default): entries once a round is under way. `start_lists`: also heat-sheet entries for rounds that have not run yet. Open: Meet Operations ignores a value it does not know.",
					"items": {
						"type": "string",
						"anyOf": [
							{
								"enum": ["results", "start_lists"]
							},
							{
								"$ref": "#/definitions/laterValue"
							}
						]
					}
				},
				"accepts": {
					"type": "array",
					"description": "The Open Meet Exchange versions this destination reads, newest first, such as [\"1.0\"]. Listing a version accepts every later minor of its major: [\"1.0\"] reads every 1.x. Optional: without it, Meet Operations writes a version of the major of the document or card that named this destination. Meet Operations sends only a major listed here.",
					"minItems": 1,
					"items": {
						"type": "string",
						"pattern": "^\\d+\\.\\d+$"
					}
				}
			}
		},
		"round": {
			"type": "object",
			"description": "Round-level state, written by Meet Operations. Entries point at a round by `round` number.",
			"required": ["round", "status"],
			"properties": {
				"round": {
					"type": "integer",
					"minimum": 1
				},
				"label": {
					"type": "string",
					"description": "How the round is named on paperwork, e.g. Prelims, Final. Shown, never used to decide which round is the final."
				},
				"final": {
					"type": "boolean",
					"description": "True on the round whose places are the event's result, including the only round of a single-round event. Omitted on every other round, and on every round while the final is not yet known. On a round that is not the final, `overall_place` is the place across that round only."
				},
				"status": {
					"type": "string",
					"description": "Where the round stands. `upcoming` not run yet; `started` under way, some results may be in; `cancelled` will not run; `unofficial` every heat has run and results may still change; `under_review` a protest or review is open; `official` final, unless a correction follows. Open, and fails safe: a reader treats a value it does not know as not official.",
					"anyOf": [
						{
							"enum": ["upcoming", "started", "cancelled", "unofficial", "under_review", "official"]
						},
						{
							"$ref": "#/definitions/laterValue"
						}
					]
				},
				"scheduled_at": {
					"$ref": "#/definitions/dateTime",
					"description": "When the round is planned to start. The meet's only schedule: a registration document carries none. A plan, never a start: when a heat went is its `started_at`."
				},
				"timing": {
					"type": "string",
					"description": "How times in this round were taken: `hand` (stopwatch or hand-operated timer), `fat` (fully automatic, photo-finish), `transponder` (chip). Omitted when Meet Operations does not record it. Open; a reader treats a value it does not know as absent.",
					"anyOf": [
						{
							"enum": ["hand", "fat", "transponder"]
						},
						{
							"$ref": "#/definitions/laterValue"
						}
					]
				},
				"place_by": {
					"type": "object",
					"description": "Which time decided places in a round that has net times: `gun` (`result`) or `net` (`net_result`). Absent when the round has gun times only, which then decide every place.",
					"properties": {
						"overall": {
							"type": "string",
							"enum": ["gun", "net"],
							"description": "Overall and gender places."
						},
						"groups": {
							"type": "string",
							"enum": ["gun", "net"],
							"description": "Places within award groups (`group_places`)."
						}
					}
				},
				"heats": {
					"type": "array",
					"description": "Heat or flight records for this round, where Meet Operations holds something about a heat itself. Entries still name their heat by number. A round run as one race, such as a cross country or road race, lists at most heat 1, to carry its started_at; an entry with no heat belongs to it.",
					"items": {
						"type": "object",
						"required": ["heat"],
						"properties": {
							"heat": {
								"type": "integer",
								"minimum": 1
							},
							"started_at": {
								"$ref": "#/definitions/dateTime",
								"description": "When the heat's start signal went, as recorded."
							},
							"wind_mps": {
								"type": "number",
								"description": "Official wind for the heat in metres per second, where one is recorded."
							}
						}
					}
				}
			}
		},
		"teamScores": {
			"type": "object",
			"description": "Team standings, written by Meet Operations when the meet is scored. Values arrive computed; render them, never recompute them.",
			"properties": {
				"id": {
					"$ref": "#/definitions/id",
					"description": "This block's id, the same from one document to the next. A `partial` document replaces the blocks it carries by `id`."
				},
				"scope": {
					"type": "object",
					"description": "What this standing covers: one event, one division across its events, or the whole meet, and whose standings they are.",
					"required": ["type", "gender"],
					"properties": {
						"type": {
							"type": "string",
							"description": "Open: a reader that does not know the value skips the block rather than show standings it cannot label.",
							"anyOf": [
								{
									"enum": ["event", "division", "meet"]
								},
								{
									"$ref": "#/definitions/laterValue"
								}
							]
						},
						"id": {
							"$ref": "#/definitions/id",
							"description": "The event or division id. Absent when `type` is `meet`."
						},
						"gender": {
							"$ref": "#/definitions/eventGender",
							"description": "Whose standings these are, always present: `M`, `F`, or `X` when teams are scored separately by gender (a co-ed school's boys' and girls' scores are two blocks), `C` when the standings count every gender together."
						}
					}
				},
				"standings": {
					"type": "array",
					"items": {
						"type": "object",
						"required": ["team_id"],
						"properties": {
							"team_id": {
								"$ref": "#/definitions/id",
								"description": "The team, by its `id` in `teams`."
							},
							"place": {
								"type": "integer",
								"minimum": 1,
								"description": "Two standings in one block with the same place are tied."
							},
							"points": {
								"type": "number"
							},
							"complete": {
								"type": "boolean",
								"description": "Whether the team fielded enough scorers to score. An incomplete team carries no `place`, no `points`, and no `entries`."
							},
							"entries": {
								"type": "array",
								"description": "The entries that scored or displaced for this standing, so a results page can print a team's line without recomputing it. Each entry's own `points` is its value. Optional; Meet Operations writes it where it holds it.",
								"items": {
									"type": "object",
									"required": ["entry_id", "role"],
									"properties": {
										"entry_id": {
											"$ref": "#/definitions/id"
										},
										"role": {
											"type": "string",
											"description": "`scorer` counted in the team total; `displacer` did not count but pushed other teams' runners back. Open; a reader treats a value it does not know as absent.",
											"anyOf": [
												{
													"enum": ["scorer", "displacer"]
												},
												{
													"$ref": "#/definitions/laterValue"
												}
											]
										}
									}
								}
							}
						}
					}
				}
			},
			"required": ["id", "scope", "standings"]
		},
		"wave": {
			"type": "object",
			"description": "A start wave in a road or trail race. An entry names its wave with `wave_id`. Registration may assign waves; a results document carries the waves run.",
			"required": ["id", "name"],
			"properties": {
				"id": {
					"$ref": "#/definitions/id"
				},
				"name": {
					"type": "string"
				},
				"offset_ms": {
					"type": "integer",
					"minimum": 0,
					"description": "How long after the start of the athlete's event this wave started, in milliseconds. A `result` is already timed from the wave's own start."
				}
			}
		},
		"eventCode": {
			"type": "string",
			"description": "What the event is, how far, and how it ranks: the only field that says any of them. Codes are defined per sport; the spec tabulates them. A race in metres (`100`, `5000`) or miles (`1MILE`, `3.1MILE`), `HMAR`, `MAR`; hurdles in metres with `H` (`110H`); a steeplechase with `S` (`3000S`); a race walk with `W` (`5000W`, `1MILEW`); an even relay as legs × leg (`4X100`, `4X1MILE`, `4X110H`); a medley by its total (`800R`, `1000R`, `1600R`, `3200R`, `4000R`); a field event (`LJ`, `TJ`, `SLJ`, `HJ`, `PV`, `SHJ`, `SP`, `DT`, `HT`, `JT`, `WT`, `TJT`, `SBT`, `BBT`, `CT`); or a multi-event (`DEC`, `HEP`, `PENT`), for any gender, whose component events Meet Operations builds. A race's code is its advertised distance, not what the course measured, and each distance has one code: a half marathon is always `HMAR`, a marathon always `MAR`. Running events and relays rank lowest time first, field events by best mark, multi-events by points. Open: a later minor version adds codes. A writer sends only a code this version defines for the meet's sport, never one of its own; a reader that meets a code it does not know leaves that event and its entries out, tells the operator, and reads the rest of the meet.",
			"anyOf": [
				{
					"pattern": "^(LJ|TJ|SLJ|HJ|PV|SHJ|SP|DT|HT|JT|WT|TJT|SBT|BBT|CT|DEC|HEP|PENT|HMAR|MAR|(800|1000|1600|3200|4000)R|[2-9]X[1-9][0-9]*H?|[2-9]X([1-9][0-9]*(\\.[0-9]+)?|0\\.[0-9]+)MILE|[1-9][0-9]*[HSW]?|([1-9][0-9]*(\\.[0-9]+)?|0\\.[0-9]+)MILEW?)$"
				},
				{
					"$ref": "#/definitions/laterValue"
				}
			]
		}
	},
	"allOf": [
		{
			"not": {
				"required": ["publish"]
			}
		}
	]
}
