Draft 1.0
Results, described once, readable by anything.
A results document should answer four questions: who competed, what was measured, how those measurements compare, and what happened to those who did not finish. Generic formats answer only the second. OpenResult answers all four — which is what lets a consumer display a correct ranking without knowing the sport.
The document carries the meaning
A spreadsheet carries values. Here every quantity declares what it is, in what unit, at what precision, and which direction wins. That is what makes automatic ranking possible at all.
Ranks are derived, not asserted
A ranking says how to order, never the order itself. Two conforming consumers reach the same standings from the same file, ties included — which is checked here against a second implementation on every commit.
Nothing to evaluate
No expression language, no formula a reader must execute. Ordering is a deterministic sort over declared values, so a JSON encoder is enough to produce a document in any language.
A whole document
This is complete and valid. Three swimmers, one measure, one ranking — and no ranks anywhere, because a consumer computes them.
{
"openresult": "1.0",
"title": "Club meet — 100 m freestyle",
"lang": "en",
"measures": [
{ "id": "time", "label": "Time", "kind": "duration",
"unit": "s", "precision": 2, "betterWhen": "lower" }
],
"participants": [
{ "id": "a", "name": "Ana Ruiz" },
{ "id": "b", "name": "Bea Nowak" },
{ "id": "c", "name": "Cleo Adeyemi" }
],
"results": [
{ "participant": "a", "values": { "time": 56.44 } },
{ "participant": "b", "values": { "time": 55.10 } },
{ "participant": "c", "status": "dnf" }
],
"rankings": [
{ "id": "main", "label": "Final", "sortBy": ["time"] }
]
}
Bea wins on 55.10. Cleo is not ranked — she did not finish — but she is still shown, because
omitting her would misrepresent the field. The times render as
55.10, not 55.1 s, because the measure declares its precision.
Post a document to the viewer
The viewer takes a document however you have one: pasted, uploaded, fetched from a URL, or posted straight from your own service.
# The document itself
curl -X POST https://openresult.dev/view \
-H 'Content-Type: application/json' \
--data-binary @results.json
# Or just tell it where to look
curl -X POST https://openresult.dev/view \
-d 'url=https://example.org/results.json'
Either returns a rendered page. There is also
GET /view?url=… when a link is easier than a form.
What it is deliberately not
It does not model how a competition is run — no fixtures, no scheduling, no scoring rules, no live timing protocol. It describes an outcome, so that the outcome outlives the software that produced it.
Where to go next
The specification
RFC-style, every rule numbered and citable. §2 through §8 is enough to build a producer or a consumer.
The examples
Twenty documents across twenty unlike domains — motocross, chess, a CPU benchmark, a photo contest — each rendered by the same viewer with no configuration.
The playground
Type a document and watch it validate and render as you go, with diagnostics pointing at the token that caused them.