# GolfNow Golf Course Scraper — Directory, Tees & Ratings (`yugenox/golfnow-courses-scraper`) Actor

Scrape the GolfNow golf course directory by country, state or city: course name, address, coordinates, phone, website, bookable on GolfNow or not, rating and reviews count, par, yardage, slope, course rating, every tee, amenities, year built and photos. US, Canada, UK, Ireland and more. No login.

- **URL**: https://apify.com/yugenox/golfnow-courses-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (community)
- **Categories:** Sports, Lead generation, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 golf courses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GolfNow Golf Course Scraper: course directory, tees and ratings

Scrape the **GolfNow course directory**: every golf course GolfNow lists in a **country, state / province or city**, in the **United States, Canada, England, Scotland, Wales, Ireland, Northern Ireland, Australia, France, Germany, Mexico** and more. For each course you get the **name, address, map coordinates, whether it sells tee times on GolfNow, the course's own phone number and website, golfer rating and number of ratings, par, yardage, slope, course rating, every tee, year built, grass, season, dress code, amenities and photos**. No login, no cookies, no GolfNow account.

### What you get

| | |
|---|---|
| **Course** | Name, GolfNow facility ID, bookable on GolfNow (yes / no), tee-time page, course details page |
| **Contact** | The course's own phone number and website, notes (bookable courses) |
| **Location** | Full address, street, city, state / province / region, ZIP / postal code, country, latitude / longitude |
| **Golf** | Holes, par, yardage, slope, USGA course rating, every tee (name, par, yards, slope, rating), year built, architects, greens and fairways grass, season, dress code |
| **Ratings** | Average golfer rating, number of ratings, % who recommend, and the breakdown: conditions, layout, pace of play, staff, value, facilities, difficulty |
| **Amenities** | Walking, spikes, credit cards, carts, rental clubs, caddies, driving range, chipping area, putting green, teaching pro, singles and fivesomes |
| **Flags & photos** | Private, premium, featured, new, Topgolf, simulator, twilight golf, SparkGolf league, Hot Deals, member pricing; main photo and course photos with captions |

### How to use it

1. In **Locations**, enter where to look:
   - a **country**: `United States`, `Canada`, `Scotland`, `Ireland`, `Australia` …
   - a **US state or Canadian province**: `Florida` or `FL`, `Ontario` or `ON`
   - a **city with its state / province**: `Scottsdale, AZ`, `Myrtle Beach, SC`, `Ajax, ON`
   - elsewhere, a **region and country** (`Kerry, Ireland`, `Fife, Scotland`) or **city, region, country** (`Anstruther, Fife, Scotland`)
2. Set **Max courses** and, if you want, **Only courses bookable on GolfNow**.
3. Run. You can also paste GolfNow course-directory, course or tee-time URLs.

Note: `CA` alone means California; write `Canada` for the country.

#### Input examples

Golf courses in Scottsdale, Arizona:

```json
{
  "locations": ["Scottsdale, AZ"],
  "maxItems": 50
}
```

Every course in Ontario and British Columbia that sells tee times on GolfNow:

```json
{
  "locations": ["Ontario", "British Columbia"],
  "onlyBookable": true,
  "maxItems": 0
}
```

Scotland's courses, plus a few specific pages:

```json
{
  "locations": ["Scotland"],
  "startUrls": [
    { "url": "https://www.golfnow.com/course-directory/us/sc" },
    { "url": "https://www.golfnow.com/courses/1049288-eagle-knoll-golf-club-details" }
  ],
  "maxItems": 500
}
```

### Output example

```json
{
  "facilityId": 7929,
  "productReviewId": 1027034,
  "name": "Camelback Golf Club - Ambiente",
  "bookable": true,
  "url": "https://www.golfnow.com/tee-times/facility/7929-camelback-golf-club-ambiente/search",
  "teeTimesUrl": "https://www.golfnow.com/tee-times/facility/7929-camelback-golf-club-ambiente/search",
  "courseDetailsUrl": "https://www.golfnow.com/courses/1027034-camelback-golf-club-ambiente-details",
  "phone": "(480) 596-7050",
  "website": null,
  "address": "7847 N. Mockingbird Lane, Scottsdale, Arizona 85253, US",
  "city": "Scottsdale",
  "state": "Arizona",
  "stateCode": "AZ",
  "postalCode": "85253",
  "country": "US",
  "latitude": 33.55397,
  "longitude": -111.934,
  "par": 72,
  "yardage": 7225,
  "slope": 138,
  "courseRating": 73.9,
  "rating": 4.5,
  "reviewCount": 1111,
  "recommendedPercent": 88.7,
  "ratingConditions": 4.47,
  "ratingPace": 4.42,
  "tees": [
    { "name": "Black", "par": 72, "yards": 7225, "slope": 138, "rating": 73.9, "unit": "yards" }
  ],
  "drivingRange": "Yes",
  "puttingGreen": "Yes",
  "isPrivate": false,
  "imageUrl": "https://exddilid.cdn.imgeng.in/app/ttf/image/hdm/7929.jpg",
  "directoryCountry": "us",
  "directoryState": "az",
  "directoryCity": "Scottsdale",
  "scrapedAt": "2026-10-01T23:13:46.486Z"
}
```

Every row has the same columns; a value GolfNow doesn't show is `null`. `phone` and `website` come from GolfNow's tee-time page, so they are filled for courses that are bookable on GolfNow.

### Use cases

- **Golf industry lead lists**: every course in a state with phone, website and address, for equipment, turf, software, cart and apparel sales.
- **Market research**: how many public courses an area has, their length, difficulty and rating, and which ones sell tee times online.
- **Travel and golf apps**: feed course data, tees, photos and coordinates into a course finder or trip planner.
- **Monitoring**: schedule a run to see courses joining or leaving GolfNow.

### FAQ

**Do I need a GolfNow account, cookies or a login?** No. The scraper reads the same public course-directory and course pages any visitor sees. It never logs in, never books anything and needs nothing from you except a location.

**Does it get tee times and green fees?** No. This actor covers the course directory. GolfNow loads tee times and prices in the browser from a separate service, and they change minute by minute.

**How fast is it?** About 2–3 pages per second. A course bookable on GolfNow takes two quick requests (a redirect and its page), other courses one, plus one page per city. A city takes a few seconds; Ontario (about 440 courses) takes about 6 minutes; the whole US directory (about 15,700 courses) takes several hours, so raise **Timeout** in the run options for very large areas. If the timeout comes first, the run stops cleanly and keeps every course it found.

**Why are some locations skipped?** A city needs its state or province (`Toronto, ON`, not `Toronto`), because many cities share a name. The run's status message lists anything it could not place and why, and those are never charged.

**What does a run cost?** You pay a small fee per run, per course saved and a much smaller fee per directory page read (country, state or city). See the Pricing tab. Courses that are gone from GolfNow, or skipped by **Only courses bookable on GolfNow**, are never charged as courses.

**Which proxy should I use?** Keep the default (Apify Proxy, datacenter). It comes with every Apify plan, including the free one. If GolfNow refuses datacenter IPs for a while, the run switches to residential proxies when your account has them, and carries on without them when it doesn't.

**Is it legal to scrape GolfNow?** This Actor only collects publicly available data: golf course listings that anyone can see on GolfNow without an account, such as the course name, address, phone number, website, ratings, tees and amenities. Collecting publicly available data is generally legal, but you're responsible for how you use it. The data describes businesses, not people: the scraper doesn't collect reviews or reviewer names, only the average ratings, and it drops any e-mail address that belongs to a named person (only general mailboxes such as info@ are kept). You must follow privacy laws such as GDPR, PIPEDA and CCPA, as well as GolfNow's terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?** No. Everything comes from pages GolfNow shows to any visitor without logging in. It never uses a login, never touches golfer accounts or bookings, and follows GolfNow's robots.txt.

*This Actor is not affiliated with, endorsed by or sponsored by GolfNow, GolfPass or Versant Media. All trademarks belong to their owners.*

# Actor input Schema

## `locations` (type: `array`):

Where to collect golf courses: a country ("Canada", "Scotland", "United States"), a US state or Canadian province ("Florida", "FL", "Ontario", "ON") or a city with its state / province ("Scottsdale, AZ", "Ajax, ON"). Elsewhere use "Region, Country" or "City, Region, Country" ("Kerry, Ireland"). Note: "CA" alone means California — write "Canada" for the country.

## `startUrls` (type: `array`):

Optional: GolfNow course-directory pages (https://www.golfnow.com/course-directory/ca/on/19036-ajax, …/us/fl, …/sct), course pages (…/courses/<id>-<name>-details) or tee-time pages of a course (…/tee-times/facility/<id>-<name>/search).

## `maxItems` (type: `integer`):

Maximum number of golf courses saved in this run. 0 = everything in your locations (the whole US directory is about 15,700 courses).

## `onlyBookable` (type: `boolean`):

Keep only courses that sell tee times on GolfNow (they also come with the course's own phone number and website). Off: every course in the directory.

## `maxConcurrency` (type: `integer`):

Pages read at the same time (request starts stay at most ~3 per second).

## `proxyConfiguration` (type: `object`):

Apify Proxy (datacenter) is the default and comes with every Apify plan. If GolfNow refuses datacenter IPs for a while, the run switches to residential proxies when your account has them.

## Actor input object example

```json
{
  "locations": [
    "Scottsdale, AZ"
  ],
  "maxItems": 10,
  "onlyBookable": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped golf courses.

## `run` (type: `string`):

Status and statistics for this run.

## `report` (type: `string`):

RUN_REPORT: how the run ended, counts, requests and proxy use.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "locations": [
        "Scottsdale, AZ"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/golfnow-courses-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "locations": ["Scottsdale, AZ"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/golfnow-courses-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "locations": [
    "Scottsdale, AZ"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/golfnow-courses-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/golfnow-courses-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/HzHfPqOa8TDoRoeVI/builds/Ne7HbFbHoy94XuUKd/openapi.json
