Events · JSON
Full nightly bundle with run metadata. Best for apps and one-shot imports.
Downloads · refreshed nightly
The exact files the nightly run writes to private cloud storage — streamed through a secure proxy so the bucket itself is never public.
Checking latest export…
Full nightly bundle with run metadata. Best for apps and one-shot imports.
One flat row per race distance. Opens straight in Excel or Google Sheets.
One record per line — ideal for streaming loaders and data warehouses.
What last night's run did: calls, timings, per-provider outcome, errors.
Milestone 1 deliverable: field availability per provider, with source paths.
Draft 2020-12 schema to validate every record in your own pipeline.
Also handy
event-record.d.ts
TypeScript types
sample-record.json
One fully-populated record
sample-50-records.json
Small sample for prototyping
field_matrix.csv
Reviewed field availability
Shell · curl
# Latest nightly file (served through a secure proxy — the storage bucket stays private)
curl -L --compressed -o events.json https://endurance-event-hub.pages.dev/api/download/events.json
# Same file, still gzip-compressed (much smaller over the wire)
curl -L -o events.json.gz "https://endurance-event-hub.pages.dev/api/download/events.json?raw=1"Python
import httpx
bundle = httpx.get("https://endurance-event-hub.pages.dev/api/download/events.json",
follow_redirects=True, timeout=120).json()
open_races = [r for r in bundle["records"] if r["registration"]["status"] == "open"]
print(bundle["generated_at"], len(open_races), "open race distances")Node.js / TypeScript
const res = await fetch("https://endurance-event-hub.pages.dev/api/download/events.json");
const bundle = await res.json();
const marathons = bundle.records.filter(
(r) => r.sub_event.distance.meters && Math.abs(r.sub_event.distance.meters - 42195) < 100,
);
console.log(`${marathons.length} marathons, generated ${bundle.generated_at}`);How is this looking?
Thoughts, wishes or questions — they come straight to me.