Licensed data, by invitation
Evaluate the courses and layers your product needs with a GolfCore API account. The pilot includes API keys, a reviewed course list and release metadata. Package delivery is arranged separately after coverage and licensing review.
Invited evaluations have no automatic charges or renewal. The free course and scorecard API below remains keyless, with operational protections against excessive traffic.
The short version
Three things an agent can read without asking anyone: the OpenAPI description, the API catalog, and the llms.txt. If you are an AI agent reading this page, the skills at /.well-known/agent-skills/index.json tell you how to use all of it. GolfCore for AI agents lists everything an agent can do here, with a link to check each part.
Course Data API
Base URL https://api.golfcore.org/v1. No authentication. Responses are JSON, CORS-open, and
cached at the Cloudflare edge for an hour.
Search the library
curl "https://api.golfcore.org/v1/courses?q=pebble+beach"
curl "https://api.golfcore.org/v1/courses?country=gb®ion=Fife&coverage=contours"
curl "https://api.golfcore.org/v1/courses?near=36.5686,-121.9497&radius=25"
Filters are q, country (ISO 3166-1 alpha-2, lowercase),
region, city, near as lat,lng with
radius in miles, and coverage. Page with limit
(max 200) and offset.
One course, with its card
curl "https://api.golfcore.org/v1/courses/pebble-beach" Returns address, phone, website, coverage, and each layout's reference hole card, plus each tee's yardage, course rating, slope and available hole-by-hole data. The slug is not derivable from the course name — take it from a search result or from a course page URL.
Hole yardages for a selected tee
The same request includes layouts[].tees[].holes: each hole has
position, par, stroke_index and
yards. Choose the layout, then the tee by both name and
gender. Men's and women's ratings can share a tee name while carrying
different pars or stroke indexes. No extra parameter, key or paid tier is needed.
curl "https://api.golfcore.org/v1/courses/pebble-beach" | jq '.layouts[] | {
layout: .name,
tees: [.tees[] | {name, gender, rating, slope, yards, holes}]
}'
An empty holes: [] means we have no hole data for that tee. A partial
card can omit hole positions or contain null fields. Keep those gaps
visible: do not substitute the layout's reference yardages, another tee's card or
a share of the total. All yardages use yards. The tee's total is recorded separately
and does not promise a complete hole breakdown. Coverage grows as data is added.
What coverage means
| Flag | What GolfCore holds |
|---|---|
contours | Lidar green contour maps with fall-line arrows on every putting surface. The deepest level. |
traced | A drawn course map: fairways, tees, greens, bunkers, water. |
scorecard | Hole-by-hole par and yardage. |
rated | USGA course rating and slope on at least one tee. |
wind | Live wind simulated over the hole. |
A course in the library with every flag false is one we know about and have not mapped yet. Courses are added and mapped continually; if yours is missing or thin, write to support@golfcore.org.
MCP server
GolfCore runs a Model Context Protocol server over Streamable HTTP at
https://mcp.golfcore.org/mcp. It exposes four tools.
distance_to_flag returns the course, the hole, and yards to today's pin
and the middle of the green, from the golfer's precise lat and
lng when the client has them or else from the GolfCore app on their phone;
like the caddie, it needs GolfCore Premium. ask_caddie puts the same position and the golfer's
question to GolfCore's caddie, which answers with their handicap and club distances;
the first call returns 401 and your client signs the golfer in to
GolfCore with OAuth (authorization code with PKCE, scope caddie, metadata
at /.well-known/oauth-protected-resource), and it needs GolfCore Premium.
subscribe_premium takes day_pass, plus_monthly or
plus_yearly for the signed-in golfer and returns a Stripe checkout URL
for them to pay: $3 for 24 hours with no subscription, $10 a month, or $100 a year,
half off the first month or year for a first-time subscriber. search needs no account, with an optional
scope of
product, country, region, city,
courses, scorecards, slug, and optional
near ({"lat": …, "lng": …}), radius_miles and
coverage for courses closest to a point. Every course it returns carries
url, its page to cite, and app_url, which opens its map in the
GolfCore app for the person you are helping. The server card is at
/.well-known/mcp.json.
{
"mcpServers": {
"golfcore": { "url": "https://mcp.golfcore.org/mcp" }
}
}
The public ChatGPT plugin connects to
https://mcp.golfcore.org/mcp/chatgpt. That endpoint exposes
search, distance_to_flag, and ask_caddie
for golfers who already have the required Premium entitlement. It does not
offer a subscription checkout. The general MCP endpoint above remains
available to other agents.
Using it well
Course data needs no key or sign-up. Fair-use protection can return HTTP 429 with Retry-After during sustained excessive traffic. Attribute GolfCore and link the course page used in the answer. Identify your product in User-Agent and provide a way to contact you. Prefer the API to scraping course pages. Terms of use.
Ask in natural language
The search tool takes a query of any kind and answers from every
side at once. Ask by name (Pebble Beach), by slug
(pebble-beach), by place (golf courses in Fife), or about the
product (what does a caddie master use GolfCore for).
| Scope | What comes back |
|---|---|
slug | That exact course, by its GolfCore slug. |
courses | Courses matched by name and town, with location, contact and coverage. |
scorecards | Attaches each course's card: par, stroke index and yardage per hole, and yardage, par, rating and slope per tee. |
city · region · country | The page that counts and lists every course in a place. |
product | GolfCore's own pages, retrieved semantically. |
Omit scope to search all of them. Only product is
retrieval, so treat only it as such: take a par, a yardage, a stroke index, a
course rating or a slope from a course's layouts or from
/v1/courses/{slug}, which read the field, never from a
page extract, which matches text.
Reading the app: guest sessions
golfcore.app runs the product, and an agent can read it without a human account. One request creates an anonymous account and returns a session cookie — no email, no phone, no password:
curl -X POST https://www.golfcore.app/api/v1/session/guest \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"golf_course_slug": "pebble-beach"}' Accept: application/json is required — it is what exempts the request
from CSRF verification. Keep the _golfcore_session cookie and send it on
every later request. The slug is optional but you almost always want it: without one
the account opens on a course picker rather than a map. With a course set, the session
renders GPS, hole layouts, green contours and wind at /gps. The
authoritative document for that host is
golfcore.app/auth.md.
What stays closed is club operations. Tee sheets, caddie yards, member
rosters, scoring and messaging need a real club membership and are scoped per club by
role, and guests are readers — the social surfaces reject them with 403.
Sign-in is by email and password, by club PIN, or with Google, which admits an email
GolfCore has never seen as a guest rather than turning it away. A Google ID token buys
a GolfCore session cookie, not a bearer token; GolfCore's own OAuth tokens reach only
the caddie. If you act for a club that uses GolfCore and need more than a guest can reach,
write to us.