Skip to content
Caddy Scout
DiscoverTrip Planner
API Reference — v1

API Documentation

The Caddy Scout REST API gives you programmatic access to 40,000+ golf courses across the UK and Europe. All responses are JSON. All authenticated endpoints require a bearer token.

Get an API key View pricing →
Quick startAuthenticationBase URLEndpointsSearchRate limitsError codes

Quick start

1. Create a free account and copy your API key from the dashboard.
2. Pass it as a Bearer token on every request.
3. Hit the courses endpoint to verify things are working.

Fetch links courses in Scotland
curl https://caddyscout.com/api/v1/courses \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -G \
  -d "country=GB" \
  -d "courseType=links" \
  -d "limit=5"
Example response (truncated)
{
  "courses": [
    {
      "id": "clx9abc123",
      "name": "Royal Dornoch Golf Club",
      "slug": "royal-dornoch",
      "country": "GB",
      "city": "Dornoch",
      "courseType": "links",
      "holes": 18,
      "lat": 57.8694,
      "lng": -4.0271,
      "greenFeeWeekend": 230,
      "currency": "GBP",
      "hasDrivingRange": false,
      "hasProShop": true
    }
  ],
  "total": 312,
  "page": 1,
  "limit": 5
}

Authentication

All endpoints except /api/v1/status require authentication. Pass your API key as a Bearer token in the Authorization header.

Authorization: Bearer sk_live_your_key_here

Key prefixes

sk_live_ — live key, counts against your daily quota

sk_test_ — test key, returns fixture data, quota-free

Never expose your live key in client-side code or public repositories. Rotate compromised keys instantly from the dashboard.

Base URL

https://caddyscout.com/api/v1

All endpoints are versioned under /v1. Breaking changes will increment the version prefix.

Endpoints

GET/api/v1/statuspublic

Health check — no authentication required. Returns {"status":"ok"}.

GET/api/v1/courses

Paginated list of courses. Supports rich filtering across type, location, price, and facilities.

Query parameters

pageintegerPage number (default: 1)
limitintegerResults per page, max 100 (default: 20)
qstringFree-text search across name, city, and country
countrystringISO 3166-1 alpha-2 country code (e.g. GB, IE)
courseTypestringlinks · parkland · heathland · coastal · desert · mountain · moorland · woodland
venueTypestringgolf_course · driving_range · simulator · social_golf
difficultystringbeginner · intermediate · advanced · championship
holesinteger9, 18, 27, or 36
isPublicbooleantrue to return only publicly accessible courses
hasMembershipbooleantrue to return only membership clubs
maxGreenFeeintegerMaximum weekend green fee in local currency
minGreenFeeintegerMinimum weekend green fee in local currency
verifiedbooleantrue to return only Caddy Scout–verified listings
Example
GET /api/v1/courses?country=IE&courseType=links&holes=18&limit=10
GET/api/v1/courses/:id

Fetch a single course by its Caddy Scout ID or URL slug. Returns all fields including hole-by-hole data where available.

Path parameter

:idrequiredstringCaddy Scout course ID (cuid) or slug, e.g. royal-dornoch

Search endpoint

The search endpoint supports free-text queries and returns both matching courses and geocoded location results (postcodes, cities, Eircodes). Useful for building autocomplete or map-fly-to UIs.

GET/api/v1/search

Query parameters

qrequiredstringSearch query. Min 2 characters. Supports course names, city names, UK postcodes, Eircodes, and US/CA zip codes.
limitintegerMax results returned (default: 8, max: 20)
countrystringBias results toward a country (ISO 3166-1 alpha-2)
latnumberLatitude for proximity sorting
lngnumberLongitude for proximity sorting
Response shape
{
  "results": [ /* CourseSummary[] — matched courses */
    {
      "id": "...",
      "name": "St Andrews Links — Old Course",
      "city": "St Andrews",
      "country": "GB",
      "lat": 56.3402,
      "lng": -2.8027,
      "holes": 18,
      "greenFeeWeekend": 295
    }
  ],
  "locations": [ /* geocoded place results */
    {
      "label": "St Andrews",
      "sublabel": "Fife, Scotland",
      "lat": 56.3398,
      "lng": -2.7967,
      "zoom": 13
    }
  ]
}

Rate limits

Quotas reset every 24 hours at midnight UTC. Every response includes headers so you can track consumption before hitting a 429.

HeaderDescription
X-RateLimit-LimitYour plan's daily request limit
X-RateLimit-RemainingRequests remaining in the current 24 h window
X-RateLimit-ResetISO 8601 timestamp when the window resets (UTC)
Retry-AfterSeconds to wait — only present on 429 responses

Plan limits

Free

100 / day

Starter

5,000 / day

Professional

50,000 / day

Enterprise

Unlimited

Need higher limits? Compare plans →

Error codes

All errors return a JSON body with a error string and an optional message field.

StatusCodeMeaning
400bad_requestMissing or invalid query parameter
401unauthorizedMissing or malformed Authorization header
403forbiddenValid key but insufficient plan for this endpoint
404not_foundCourse ID or slug does not exist
422unprocessableRequest understood but validation failed
429rate_limit_exceededDaily quota exhausted — check Retry-After header
500internal_errorSomething went wrong on our end
Error response example
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
Content-Type: application/json

{
  "error": "rate_limit_exceeded",
  "message": "Daily quota of 100 requests exhausted. Resets at 2026-05-27T00:00:00Z.",
  "retryAfter": 3600
}

Ready to start building?

Free tier, no credit card required. Upgrade any time.

View pricingGet API key