Junior golf tournament schedules, venues and tours, free to use with attribution. This page covers the endpoints, how fresh the data is, what you may do with it, and what every field means.
Base URL: https://www.tourdata.golf/api/v1. Responses are JSON shaped { data, meta }.
| Endpoint | What it returns |
|---|---|
GET /tournaments | Tournament list. Filters: tour, state, gender, status, level, from/to (on date_start), pbe, min_stars, updated_since. Paging: limit (default 100, max 2000), offset. Sorting: sort, order. |
GET /tournaments/{id|slug} | One tournament by UUID or slug. |
GET /tournaments/search | Name typeahead: q (2+ chars), gender. |
GET /tours | tour_code → name mapping with event counts. |
GET /courses | Courses: q, state, slug, limit, offset. |
GET /courses/{id|slug} | One course. |
GET /pbe-events | AJGA Performance Based Entry events and star awards. |
The list response includes meta.total, meta.has_more and meta.next_offset. A full upcoming season is roughly 1,000 rows, so page until has_more is false.
| Data | Access |
|---|---|
| Tournaments, search, tours, courses, PBE events | Open: no key needed |
| Players, results, leaderboards, rosters/fields, rankings, recruiting, projections | Partner API key: Authorization: Bearer <key> |
Without a key you get 100 requests per day per IP. Keys get a higher daily limit. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and an over-limit request returns 429 with Retry-After. A free key is the easiest way to get higher limits and lets us reach you about changes. Ask at [email protected].
Responses are cached at the edge for up to 5 minutes (courses and tours: 1 hour).
| What | When | Notes |
|---|---|---|
| New events, every tour | Weekly · Wednesday | Adds newly announced events; does not edit existing ones. |
| Full schedule refresh, every tour | Monthly · the 2nd | Re-reads every upcoming event: dates, venue, fees, registration. |
So a newly announced event appears within about a week, and a change to an existing event (new dates, a fee update) is picked up within about a month. updated_at on a record tells you when its published content last changed. The MCP get_data_freshness tool reports the latest change per tour.
Tournament, schedule, course and tour data is free to use, including commercially. You may:
We ask that you:
tourdata_url is ideal; the homepage is fine;official_url to register, and don't present the data as the official record. Organizers can change details at any time;Player, results and roster data is not covered by these terms and needs a partner agreement.
updated_at moves only when a record's published content changes, not when we re-score its quality. To sync, remember the largest updated_at you have seen and ask for everything since then, oldest first:
Ordering is stable (id breaks ties), so offset paging won't skip rows. Records are never deleted. A cancelled event stays in the feed with status: "cancelled". Run a full pull now and then (monthly) as a safety net.
| Field | Meaning |
|---|---|
id | Permanent UUID. Never changes once created. Use it as your foreign key. |
slug | Unique, human-readable ID (e.g. taylormade-junior-all-star-ca-2026). Also accepted by /tournaments/{id}. |
tour_code, external_id | tour_code is the tour (see /tours). external_id is the organizer's own event ID, unique within its tour_code when present. |
recurring_event_id | Reserved for linking yearly editions of the same event. Not populated yet. |
status | active · completed · cancelled · postponed. Treat active with a past date_end as completed. Rescheduled events keep active with new dates. |
date_start, date_end, registration_opens, registration_closes | Local calendar dates at the venue (YYYY-MM-DD). No times, no time zone. |
location_*, address, course_name, course_id, country_code | Venue. course_id links to /courses/{id} when matched. |
entry_fee, entry_fee_low, entry_fee_high, is_fee_estimated | Whole currency units as published (USD for US events). null = not published, 0 = free. Low/high give a range when fees vary by division. |
gender_type | boys · girls · mixed (both, competing in separate or combined divisions) · null if unknown. |
age_divisions | Array of organizer-defined division labels, e.g. ["11 & Under", "12-14", "15-18"]. Not normalized. Use age_low / age_high for the overall eligible range. |
competitive_level | Elite · National · Regional · Local. |
ranked_by | Comma-separated ranking codes exactly as the organizer lists them, e.g. AJGA(B&G),JGS,TUGR,WAGR. Common codes: AJGA (with (B)/(G)/(B&G) for boys/girls), JGS (Junior Golf Scoreboard), WAGR (World Amateur Golf Ranking), GJGR (Global Junior Golf Rankings). Split on commas and trim. |
is_ajga_pbe, pbe | pbe is the authoritative AJGA Performance Based Entry block (max_stars, per-division awards, has_full_exemption, source_url), or null. is_ajga_pbe is a simple flag that the event is a PBE event; when pbe is present, use it. |
website_url, registration_url | The organizer's event page, and a separate registration link when one is published (rare). |
official_url | Where to send people: registration_url if present, else website_url, else the organizer's event page built from external_id (AJGA, HJGT). null only when none is known. |
tourdata_url | Public tourdata.golf page for the event. Use it for the attribution link. |
scoring_diff, signing_diff, diff_*, signee_* | Junior Golf Scoreboard scoring differential: score minus course rating. Lower is better; negative means the player beat the rating (rank 1 is about −9.4, roughly +4 is rank 4,000). Not a handicap, so never show a plus sign on positive values. Values are returned signed and unchanged; the differential endpoint also sends meta.sign: "lower-is-better". |
created_at, updated_at | ISO timestamps (UTC). updated_at moves only when published content changes. |
Connect Claude, Cursor or any MCP client to https://www.tourdata.golf/api/mcp (streamable HTTP, no key). It serves the same tournament records as /api/v1/tournaments, plus courses. It has no player or results data.
| Tool | Does |
|---|---|
list_tours | Every tour with its code, name and event count. Start here. |
search_tournaments | Filter by tour (code), state, dates, age, gender, status. |
get_tournament | Full record by id or slug, with PBE stars and course. |
search_courses | Find courses by name, city or state. |
get_course | Course details plus recent and upcoming events. |
get_data_freshness | Last change per tour and the refresh schedule. |
official_url to register. See Usage terms.record_*_score fields. Display every record the API returns. Our own pages note that details should always be confirmed with the organizer, and we suggest you do the same./api/v1/tournaments. That is the canonical endpoint. /api/v1/browse was the name used in older docs and is kept as an alias that returns the same data.date_start, date_end, registration_opens, registration_closes) are plain local calendar dates at the venue, with no time component. Exact deadline times aren't collected. Treat a deadline as the end of that local day and derive the zone from location_state / lat-lng if you need one.id (UUID) is permanent: it never changes once a record is created. slug is also unique and stable. (tour_code, external_id) is unique whenever external_id is present (a small number of manually added events have none). recurring_event_id is not populated today; don't rely on it.active, completed, cancelled, postponed. Cancellations are marked cancelled. A postponed or rescheduled event usually keeps active with new dates after the next refresh. Past events can still read active, so treat active with a date_end in the past as completed. Records are never deleted.updated_since plus sort=updated_at&order=asc. The default order is date_start descending with id as the tiebreaker. See Incremental sync.country_code other than US) are in the organizer's local currency. null means the fee isn't published; 0 means free. is_fee_estimated flags fees we inferred rather than read.registration_url is only set when an organizer publishes a separate registration link, which is rare. Use official_url: it is registration_url when present, else website_url, the organizer's official event page.ranked_by is a comma-separated list of ranking codes as the organizer publishes them, and it can include WAGR. The pbe block is authoritative for stars. gender_type is boys, girls or mixed. age_divisions are organizer-defined labels.GET /api/v1/tours returns code, name, alt_codes and event counts, and the MCP list_tours tool returns the same codes.Something missing? Email [email protected], or browse the data.