OpenSourceGolf Initiative

The Open Course
Data Model

A free, open, community-maintained standard for structured golf course data — designed so any developer, researcher, or app builder can read it, write it, and build on top of it without permission or proprietary lock-in.

Fully Open — CC BY 4.0
Structured JSON Schema
Any Course, Any Platform
Community Contributed

What is Open Course?

Golf course data that belongs to everyone.

Golf is full of proprietary course databases locked inside paid subscriptions and closed APIs. Open Course is our answer to that — a lightweight, human-readable JSON data model that describes a golf course completely enough to power real, game-day applications.

T'doff uses Open Course as its native data layer. Every course powered by T'doff is represented as an Open Course document. That means the data that improves your game is transparent, auditable, and exportable — not trapped.

You can use Open Course data to build GPS apps, handicap trackers, practice simulators, course-review platforms, or anything else a golf developer can imagine. No license fees. No API keys. No middlemen.

18 Holes per course document
4 Tee sets supported per hole
Hazards & targets per hole
CC BY 4.0 licensed — free forever

The Specification

Schema structure

An Open Course document is a single JSON object. Here is the full structure, annotated with field purposes and types.

Top-level object

{
  "id":       "string  — UUID v4, globally unique course identifier",
  "name":     "string  — Official course name",
  "slug":     "string  — URL-safe identifier e.g. pebble-beach-golf-links",
  "location": { ... }, // see Location object
  "timezone": "string  — IANA timezone e.g. America/Los_Angeles",
  "par":      "number  — Total course par",
  "rating":   "number  — Course rating (decimal)",
  "slope":    "number  — Slope rating (integer)",
  "holes":    [ ... ], // array of 18 Hole objects
  "metadata": { ... }  // see Metadata object
}

Location object

{
  "address": "string  — Street address (optional)",
  "city":    "string  — City name",
  "state":   "string  — State / province code e.g. CA",
  "country": "string  — ISO 3166-1 alpha-2 e.g. US",
  "lat":     "number  — Latitude decimal degrees",
  "lng":     "number  — Longitude decimal degrees"
}

Hole object × 18

{
  "number":       "number  — 1–18",
  "par":          "number  — 3 | 4 | 5",
  "handicap":     "number  — Stroke index 1–18",
  "tees":         [ ... ], // array of Tee objects
  "pin_positions":[ ... ], // array of PinPosition objects
  "hazards":      [ ... ], // array of Hazard objects  (optional)
  "layup_targets":[ ... ]  // array of LayupTarget objects (optional)
}

Tee object

{
  "name":            "string  — Tee identifier e.g. Black | Gold | Blue | White | Red",
  "distance_yards":  "number  — Measured tee-to-pin carry in yards",
  "distance_metres": "number  — Metres equivalent (optional)"
}

PinPosition object

{
  "id":                       "string  — e.g. front | middle | back | custom label",
  "distance_from_front_yards":"number  — Yards from front edge of green to pin"
}

Hazard object

{
  "type":                  "string  — bunker | water | ob | trees | waste | lateral",
  "side":                  "string  — left | right | centre | carries (optional)",
  "distance_from_tee_yards":"number — Carry distance to clear/avoid hazard (optional)",
  "notes":                 "string  — Free-text description (optional)"
}

LayupTarget object

{
  "label":               "string  — e.g. Layup | Short-side safe | Bail right",
  "distance_from_tee_yards":"number — Carry distance to target area"
}

Metadata object

{
  "contributed_by": "string  — GitHub handle or org name",
  "last_updated":   "string  — ISO 8601 date e.g. 2026-02-22",
  "version":        "string  — Semver of this document e.g. 1.0.0",
  "license":        "string  — Always CC BY 4.0"
}

Full Example

A complete one-hole document

This is what a real Open Course record looks like for a single hole. Scale it to 18 and you have a full course.

{
  "id": "a3f1c920-8e44-4b2d-bf63-1d7e9a0c5521",
  "name": "Harbour Pines Golf Club",
  "slug": "harbour-pines-golf-club",
  "location": {
    "city": "Gosford",
    "state": "NSW",
    "country": "AU",
    "lat": -33.4172,
    "lng": 151.3526
  },
  "timezone": "Australia/Sydney",
  "par": 72,
  "rating": 73.2,
  "slope": 137,
  "holes": [
    {
      "number": 1,
      "par": 4,
      "handicap": 11,
      "tees": [
        { "name": "Black", "distance_yards": 412 },
        { "name": "Blue",  "distance_yards": 391 },
        { "name": "White", "distance_yards": 368 },
        { "name": "Red",   "distance_yards": 312 }
      ],
      "pin_positions": [
        { "id": "front",  "distance_from_front_yards": 6  },
        { "id": "middle", "distance_from_front_yards": 17 },
        { "id": "back",   "distance_from_front_yards": 29 }
      ],
      "hazards": [
        {
          "type": "bunker",
          "side": "left",
          "distance_from_tee_yards": 230,
          "notes": "Fairway bunker, steep face"
        },
        {
          "type": "water",
          "side": "right",
          "distance_from_tee_yards": 195,
          "notes": "Lateral hazard runs entire right side"
        }
      ],
      "layup_targets": [
        {
          "label": "Layup short of bunker",
          "distance_from_tee_yards": 210
        }
      ]
    }
  ],
  "metadata": {
    "contributed_by": "opensourcegolf",
    "last_updated": "2026-02-22",
    "version": "1.0.0",
    "license": "CC BY 4.0"
  }
}

Build With It

How to leverage Open Course in your project

The model is intentionally simple — a JSON file you can store, query, or serve any way you like.

Flat file storage

Each course is a single .json file. Drop them in a folder, a CDN, or commit them straight to a GitHub repo. Zero database required to get started.

REST or GraphQL API

Wrap the files in any HTTP server and you have a course data API instantly. The flat structure maps directly to REST routes — /courses/:id/holes/:number.

Mobile apps

Bundle course documents in your app binary for offline play. Parse with any JSON library on iOS, Android, or React Native — no proprietary SDK required.

GPS & mapping

Combine lat / lng from the location object with hole distances and hazard positions to render tee-to-green overlays on any mapping platform.

Handicap & scoring

Par, stroke-index, and tee distances are all first-class fields. Your handicap calculator or scorecard app can consume Open Course documents directly.

AI & analytics

Structured hazard, layup, and pin-position data feeds naturally into ML models for shot recommendation, course strategy, and performance analysis pipelines.

Open Course by OpenSourceGolf

Build something great for golf.

The spec is live, the schema is stable, and the community is growing. Grab the template and ship your first course today.

CC BY 4.0 — Free Forever JSON Schema Validated No API Key Needed