Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trackday

Find motorsport track days — HPDE, time trials, open-track/lapping, autocross, and wheel-to-wheel racing — near you, from the comfort of a terminal instead of the motorsportsreg.com website.

It queries MotorsportReg's public Global Events Calendar (GEC) GraphQL API. No account, no login, no scraping.

Install

uv tool install trackday                 # from PyPI
uv tool install --editable .             # from a source checkout

This puts trackday in ~/.local/bin with its dependencies in an isolated environment, the same way uv tool installs ruff — so the command works from any directory. That matters if you want the agent skill, which assumes a bare trackday is runnable everywhere; trackday skill install refuses to install if it isn't. pipx install trackday works equally well.

A project-local uv pip install -e . is fine for development, but the entry point then exists only inside that venv.

Quick start

# First run: create the config interactively (validates your postal code)
trackday setup

# ...or set values individually
trackday config set postalcode 94010
trackday config set radius_mi 100

# What's running near me in the next ~4 months?
trackday search

# Just HPDE and time trials this summer
trackday search --type hpde --type tt --from 2026-06-07 --to 2026-09-01

# Only events within 60 miles, at Sonoma, as JSON
trackday search --radius 60 --track sonoma --json

# Export a calendar file to import into Google/Apple Calendar
trackday search --type hpde --ics hpde.ics

# What kinds of events are available nearby?
trackday types

# Full detail for one event (id comes from `search --json`)
trackday show <event-id>

Event types (--type)

Bucket Aliases you can pass Includes (raw MSR disciplines)
HPDE hpde, de HPDE, Driver Education
Time Trial tt, time trial, timeattack Time Trial, Time Attack
Open Track open, lapping, trackday Open Track, Lapping, Track Day
Autocross ax, autox, autocross,solo Autocross/Solo, RallyCross
Racing race, w2w Club/Pro/Endurance/Vintage/Spec racing
Other other clinics, concours, rallies, etc.

Membership/gift-card/test-event "noise" is filtered out by default; pass --include-noise to keep it.

Registration status

Every search shows whether each event is actually open for registration, with the closing date when there is one — an event you can't enter is rarely the one you want.

MotorsportReg's search endpoint returns a stale snapshot: measured against the live site, its registration status was wrong for 11% of events and its registration dates for 16%, including one that was 459 days out of date. Worse, the errors run in the direction that matters — it reported "open" for events that had already closed. So trackday re-checks each event against the authoritative single-event endpoint before showing it to you.

The same check catches events that have been withdrawn entirely: the search index still returns events whose detail record and public page are both gone (2 of 78 in a typical Bay Area search). Those are dropped rather than shown with a URL that 404s.

That costs one request per event, which is why it happens after filtering — only the events you're actually going to see get checked (78 events takes ~4s cold, ~0.3s cached). Pass --no-status to skip it, at the cost of unverified statuses and the odd dead event. In JSON output, status_verified tells you whether a given event's status was confirmed; events that fail the check keep the search API's value and are flagged rather than dropped.

Distance and the 200-mile ceiling

--radius is a true great-circle limit in miles, applied locally. --max-distance is an alias for it; if you pass both, the tighter one wins.

MotorsportReg's API ignores the radius it is sent and always returns everything within 200 miles, so no search can reach further than that no matter what you ask for — --radius 500 warns and behaves as --radius 200. The measurements behind that claim are in docs/api-notes.md.

Use with an AI agent

trackday ships an agent skill that teaches assistants how to drive the CLI — the JSON workflow, the type taxonomy, the distance semantics, and the failure modes. Install it once:

trackday skill install          # -> ~/.claude/skills/trackday

It symlinks by default, so upgrading trackday also updates the skill. Use --copy for a standalone copy, --force to replace an existing install, --dir for a different skills directory, and trackday skill path to print the packaged source. The skill itself lives at src/trackday/_skill/SKILL.md.

Because the skill is user-level, it assumes trackday is on PATH everywhere — so the install refuses unless the CLI is genuinely user-level (see Install). A project venv only works while activated, which an agent in another directory won't have. Use --skip-path-check to override, or --dir .claude/skills to scope the skill to one project instead.

Configuration

Run trackday setup once — it prompts for your postal code, how far you'll travel, and how far ahead to look, checks the postal code actually geocodes, and writes ~/.config/trackday/config.toml. Until that exists (and with no --zip or .env), searching exits 1 and tells you to run it. setup needs a terminal; in scripts and agents use --zip or trackday config set instead.

Precedence (low → high): built-in defaults → ~/.config/trackday/config.toml (via trackday setup / trackday config set) → a local .env → real environment variables. Note that a .env is found by walking up from the current directory, so a project-local .env overrides your user config while you're inside that project.

.env / env keys: TRACKDAY_POSTALCODE, TRACKDAY_RADIUS, TRACKDAY_COUNTRY, TRACKDAY_API_URL, TRACKDAY_API_KEY. See .env.example.

No MotorsportReg account or credentials are needed. The MSR REST API's Basic auth requires an organization-admin account; this tool uses the public GraphQL API instead.

How it works / the widget key

  • Endpoint: https://api-v2.motorsportreg.com/graphql, which requires an x-api-key header. The key is not a credential you create — it's the public client-side widget key motorsportreg.com's own calendar ships to every browser.
  • No key is checked into this repo. On first use, trackday scrapes the key from MSR's official demo page (https://assets.motorsportreg.com/gec/demo.html) and caches it at ~/.config/trackday/api-key. If MSR rotates the key, the next 403 triggers a re-scrape automatically — no manual fixup needed.
  • To pin an explicit key instead (skipping auto-discovery), set TRACKDAY_API_KEY or trackday config set api_key <key>. Clear it with trackday config set api_key '' to return to auto-discovery.
  • ZIP → coordinates is done via the free zippopotam.us API; MSR's search takes lat/lon, not postal codes.
  • Full API notes (schema, queries, working curl examples) are in docs/api-notes.md.

Roadmap

  1. Core + CLI ← you are here
  2. Agent skill — done, see Use with an AI agent.
  3. Calendar-aware planning — extend the skill with Google Calendar / Gmail integration to check availability and plan attendance.

Development

uv pip install -e '.[dev]'
pytest

About

Find motorsport track days (HPDE, time trials, racing, autocross) near you from the terminal, via MotorsportReg's public events API.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages