API Documentation

Access golf course data programmatically using our REST API. Base URL: https://teeradar.online/api/v1

Authentication

All API requests require an API key. Include your key in the request header:

X-API-Key: tr_your_api_key_here

Or as a query parameter: ?api_key=tr_your_api_key_here

Create an account to get your free API key.

Rate Limits

Two limits apply to every key: a per-minute burst limit and a daily limit. Daily counters reset at 00:00 UTC.

Free

100/day
10/min

Starter

1,000/day
30/min · $19/mo

Pro

10,000/day
100/min · $49/mo

Enterprise

Unlimited
1,000/min · Contact us

When you hit a limit, responses return 429 Too Many Requests with a Retry-After header (seconds) and a JSON body explaining whether you tripped the minute or daily limit.

Response Envelope & Headers

All successful responses are application/json; charset=utf-8. Every response — success or error — includes a request_id field and an X-Request-Id header. Quote that ID in any support email so we can find the request in logs.

HeaderDescription
X-Request-IdUnique 16-char ID for this request. Quote in support.
X-RateLimit-LimitYour daily request limit on the current tier.
X-RateLimit-RemainingRemaining daily requests after this call.
Retry-AfterOn 429: seconds to wait before retrying.
Image URLs are always absolute (e.g. https://teeradar.online/media/courses/abc.jpg). You can use them directly in <img> tags without prefixing.

Endpoints

GET /api/v1/courses.php

Search and filter golf courses. Results are paginated.

ParameterTypeDescription
qstringSearch query (name, city, country)
countrystringFilter by country
statestringFilter by state/region
min_holesintegerMinimum number of holes
min_ratingfloatMinimum rating (1-5)
min_lengthintegerMinimum yardage
max_lengthintegerMaximum yardage
has_reviewsbooleanOnly courses with reviews
limitintegerResults per page (1-100, default 50)
offsetintegerSkip first N results
Pagination: Each response includes total, limit, offset, count, has_more, and next_offset. Keep calling with offset=next_offset until has_more is false.

Example Request:

curl -H "X-API-Key: YOUR_KEY" \
  "https://teeradar.online/api/v1/courses.php?country=United%20States&min_rating=4&limit=10"
Response:
{
  "total": 459,
  "limit": 10,
  "offset": 0,
  "count": 10,
  "has_more": true,
  "next_offset": 10,
  "courses": [
    {
      "course_id": "1027616",
      "slug": "pebble-beach-golf-links-pebble-beach-golf-links-course",
      "name": "Pebble Beach Golf Links - Pebble Beach Golf Links Course",
      "city": "Pebble Beach",
      "state": "California",
      "country": "United States",
      "rating": 4.99,
      "ratings_count": 47,
      "holes": 18,
      "length_yards": 6828,
      "description": "...",
      "tee_times_url": "https://...",
      "primary_image": "https://teeradar.online/media/courses/abc123.jpg",
      "difficulty_class": "Championship"
    }
  ],
  "request_id": "a1b2c3d4e5f60718"
}

GET /api/v1/course.php

Get detailed information for a single course. You can look up by either the numeric course_id or the human-readable slug — pass one of:

ParameterTypeDescription
slugstringHuman-readable identifier (e.g. st-andrews-links). Recommended.
idstringNumeric course_id (e.g. -1996). For backwards compatibility we also accept a slug here and fall back to slug lookup if the numeric ID isn't found.
Example (by slug):
curl -H "X-API-Key: YOUR_KEY" \
  "https://teeradar.online/api/v1/course.php?slug=st-andrews-links"
Example (by course_id):
curl -H "X-API-Key: YOUR_KEY" \
  "https://teeradar.online/api/v1/course.php?id=-1996"

First search via /api/v1/courses.php to discover valid course_id / slug values, then call this endpoint.

GET /api/v1/countries.php

List all countries with course counts.

Response:
{
  "count": 45,
  "countries": [
    {"country": "United States", "count": 17421},
    {"country": "England", "count": 1556}
  ],
  "request_id": "..."
}

GET /api/v1/states.php

List states/regions for a country with course counts.

ParameterTypeDescription
country requiredstringCountry name

GET /api/v1/leaderboard.php

Get ranked course lists.

ParameterTypeDescription
typestringtop_rated, most_reviewed, or longest (default: top_rated)
limitintegerNumber of results (1-100, default 50)
min_reviewsintegerFor top_rated: minimum review count (default 5)

Field Stability Contract

The table below describes which fields you can rely on for the lifetime of API v1. We will not silently drop or rename fields marked guaranteed within v1 — see Versioning for our deprecation policy.

Course object (list and detail responses)

FieldTypeStatusNotes
course_idstringguaranteedStable numeric primary key returned as a string (e.g. "-1996", "1027616"). Use this for long-term storage and lookups.
slugstringguaranteedURL-safe human-readable identifier (e.g. st-andrews-links). May change if a course is renamed — prefer course_id for storage, slug for URLs.
namestringguaranteedDisplay name. Defaults to "Unnamed course" if unknown.
citystringguaranteedMay be empty string ("") when unknown — never null.
statestringguaranteedState / province / region. May be empty string.
countrystringguaranteedCountry name in English. May be empty string.
ratingfloat | nullnullableAggregate rating 1.0–5.0. null when no reviews exist.
ratings_countintegerguaranteedAlways present. 0 when no reviews exist.
holesinteger | nullnullableTypically 9 or 18. null when unknown.
length_yardsinteger | nullnullableTotal yardage from the back tees. null when unknown.
descriptionstringguaranteedMay be empty string. Plain text, not HTML.
tee_times_urlstring | nullnullableAbsolute outbound URL for booking. May be null.
primary_imagestring | nullnullableAbsolute image URL. null if no image available.
difficulty_classstringguaranteedOne of: Beginner, Intermediate, Advanced, Championship. Defaults to Intermediate.

Detail-only fields (/api/v1/course.php)

FieldTypeStatusNotes
latitude / longitudefloat | nullnullableWGS84 coordinates. Use both or neither.
address, postal_code, phonestring | nullnullableContact data. Presence varies by source.
imagesarray<string>nullableGallery URLs (absolute). May be empty or absent.
par, slope, course_rating, year_built, seasonalityvaries | nullnullableOptional facts. Treat any missing key as null.

Rule of thumb: assume any field marked nullable can be null or absent. For guaranteed fields, the key will always be present in the response.

Error Handling

The API returns standard HTTP status codes. Errors always return JSON with at minimum: error (human message), status (HTTP code), and request_id.

CodeMeaning
200Success
400Bad request (missing/invalid parameters)
401Unauthorized (missing or invalid API key)
404Resource not found
429Rate limit exceeded — see Retry-After header
500Server error — retry; if persistent, contact support with request_id
Rate-limit error example:
{
  "error": "Per-minute rate limit exceeded.",
  "status": 429,
  "reason": "minute",
  "daily_limit": 100,
  "daily_used": 42,
  "minute_limit": 10,
  "minute_used": 10,
  "retry_after_seconds": 60,
  "reset": "midnight UTC",
  "request_id": "a1b2c3d4e5f60718"
}

Versioning & Deprecation

All endpoints live under /api/v1/. Within v1:

API Terms of Use

Use of the TeeRadar API is subject to our Terms and Conditions, with the following API-specific terms:

  1. Attribution. If you display TeeRadar data in a user-facing product, include a visible "Data by TeeRadar" credit linking to https://teeradar.online, unless your plan includes a white-label option.
  2. Caching. You may cache API responses for up to 24 hours. Longer caches (e.g. building a derivative database) require an Enterprise or bulk-license agreement.
  3. Redistribution. You may use the data to power your own product, including AI/ML training within your product. You may not resell or redistribute the raw dataset as a competing product.
  4. Prohibited uses. No scraping the public website, no sharing your API key with third parties, no attempts to bypass rate limits (rotating keys, parallel free accounts), and no use that violates applicable law.
  5. One key, one entity. Each API key is issued to a single person or company. To onboard a team, contact us about higher-tier plans.
  6. Suspension. We may suspend keys that abuse the service or violate these terms. We will email you before suspension where practical.
  7. SLA. Free, Starter, and Pro tiers are best-effort. Enterprise customers receive an uptime SLA per signed agreement.

Ready to get started?

Get Your Free API Key

Questions? Contact us