Leagues
A league (an event series in the API) is a season a golfer registers and pays for once. Every event linked to it draws its field from the league roster, including golfers who join after those events were created — so a Thursday-night league is set up in one place rather than event by event.
Everything on this page is public and unauthenticated. Managing a league — its roster, its teams, its linked events — is an admin API and is not part of the public surface.
List an organization's leagues
curl "https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series"
Returns leagues that are open, active or completed. Draft and private leagues are omitted; members-only leagues appear (registration is gated separately, the same way events behave).
[
{
"id": 7,
"name": "Thursday Night Simulator Scramble",
"slug": "thursday-night-simulator-scramble",
"seasonLabel": "2026 season",
"scheduleLabel": "Thursdays: 7:00-9:30",
"status": "active",
"feeMembersCents": 12000,
"feePerEntry": true,
"entrySize": 2,
"seriesImageUrl": "/media/defaults/event-series/league-1.png",
"memberCount": 20,
"linkedEventCount": 4
}
]
Two fields shape everything else:
entrySize—1is an individual league.2or more makes it a team league: golfers register as a declared pair (or foursome) that stays together all season, and the teams below apply.feePerEntry— whentruethe fee buys a whole entry, so a pair pays once between them and the partner joins free. Whenfalseevery golfer pays.
memberCount is the active roster size and linkedEventCount how many events
the league feeds, so a listing page needs no second round trip. All prices are in
cents.
scheduleLabel is free text for when the league plays, written by the
organizer — "Thursdays: 7:00-9:30". Render it as given: it is never parsed, may
say anything ("alternate Sundays, weather permitting"), and may be absent. The
authoritative dates are on the linked events; this is the one-line answer to
"when is this league?" for a listing or a header.
Get a single league
curl "https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series/{slug}"
Same shape, addressed by slug — this is the league's public landing page.
Returns 404 for a league that is private or still in draft, so a not-found and
a not-public league are indistinguishable from outside.
A league's schedule and standings
A league page usually knows one thing: the league's slug, out of its own URL. Both of the things such a page wants to show are addressable that way, so it never has to learn an internal id.
The nights, from the ordinary event list:
curl "https://api.front9.com/api/public/v1/orgs/{orgSlug}/events?filter=all&eventSeries={slug}"
eventSeries matches on the link between an event and its league — the one an
admin makes when adding a night — not on a tag or a naming convention, so the
schedule cannot drift from the league itself. It combines with the other filters
(tag, filter, year), and a slug that names no public league is a 404.
The table:
curl "https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series/{slug}/standings"
{
"standingSeries": { "id": 5, "name": "Mixed 9-Team League", "scope": "team", "seasons": [] },
"table": { "seriesId": 5, "seriesName": "Mixed 9-Team League", "rows": [] }
}
The league carries the link to its standings table (standingSeriesId), so this
resolves it for you. The series comes back alongside the table because a
season-based league needs its seasons to offer a season picker, and because
standingSeries.id is what every follow-up request uses — a different season
(?seasonId=), or a competitor's contributions — through the ordinary
standings endpoints.
A league with no standings table linked answers 200 with both fields null.
The league is real, it simply hasn't been wired up, and a page can say so rather
than show an error. Set standingSeriesId on the league to connect the two.
Start a registration
As with events and memberships, payment never flows through this API. The start endpoint hands you a hosted URL where Front9 collects the card.
curl -X POST \
"https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series/{id}/register/start"
{ "url": "https://registration.front9.com/?org=acme&eventSeries=7" }
Redirect the golfer to url to finish registering and pay for the season.
On a team league, pass ?eventSeriesTeam={teamId} to land the golfer on an
existing team rather than starting a new one — this is what a partner following
an invite link needs:
curl -X POST \
"https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series/{id}/register/start?eventSeriesTeam=12"
The parameter is passed straight through to the hosted page, so forward
org, eventSeries and eventSeriesTeam through your signup flow if the
golfer has to create an account on the way.
Team invite links
On a team league, a registrant names their partners and each is emailed a join link. Before that visitor has an account, you can read what they are joining:
curl "https://api.front9.com/api/public/v1/orgs/{orgSlug}/event-series/{id}/teams/{teamID}"
{
"id": 12,
"name": "Wolfpack",
"memberNames": ["Jamie Lee"],
"entrySize": 4,
"seatsFilled": 1,
"seatsRemaining": 3,
"complete": false
}
Deliberately narrow: names and counts only — never user ids, never the invited email addresses. It is served to whoever holds the link.
Use it to show what the visitor is joining and how many seats are open. The
seats they can fill for other people is seatsRemaining - 1 — their own seat
comes out of the same total.
Partner invites
When the invited golfer already has a Front9 account, their emailed link carries
an inviteToken. Resolve it to render the join page:
curl "https://api.front9.com/api/public/v1/event-series-invites/{token}"
{
"eventSeries": {
"id": 7,
"slug": "thursday-night-simulator-scramble",
"name": "Thursday Night Simulator Scramble",
"orgSlug": "acme",
"orgName": "Acme GC"
},
"team": {
"id": 12,
"name": "Wolfpack",
"memberNames": ["Jamie Lee"],
"entrySize": 4,
"seatsFilled": 1,
"seatsRemaining": 3,
"complete": false
},
"inviter": { "firstName": "Jamie", "lastName": "Lee" },
"email": "partner@example.com",
"feeCents": 12000,
"accepted": false
}
feeCents— what this golfer owes. Unlike an event invite nobody else is covering it: a league partner pays their own season fee. The exception is afeePerEntryleague where a teammate has already bought the entry, in which case it comes back0.accepted— the link outlives the invite. Once the golfer registers it keeps resolving withaccepted: true, so a second click can say "you're already registered" instead of erroring. It stops resolving only if the team is deleted.team— absent if the team has since been deleted.
An invited address with no Front9 account gets no token; their link carries
only org, eventSeries and eventSeriesTeam, and the team endpoint above is
all you need to render it.
404 if the token is unknown.
Related
Leagues feed the ordinary event endpoints — a league night is a normal event, so its field, tee sheet, leaderboard and live streams are the same endpoints as any other. See Real-time updates and the API reference.