Skip to main content

arccos-api banner

arccos-api

PyPI

Unofficial Python client and CLI for the Arccos Golf platform.

Arccos provides no public API. This library gives you read-only programmatic access to your own golf data — rounds, handicap, club distances, pace of play, and more.

Unofficial. Not affiliated with Arccos Golf LLC. Use with your own account only. Respect their servers (no aggressive polling).

Read-only by design. This client only sends GET requests to the Arccos data API. It cannot create, edit, or delete rounds, shots, clubs, courses, or account data. Authentication necessarily sends POST requests to the separate Arccos authentication service to log in and refresh tokens; those requests only obtain credentials and do not modify golf data.

Installation

Install the arccos-api distribution from PyPI:

pip install arccos-api

Or install the CLI with Homebrew:

brew install pfrederiksen/tap/arccos-api

Or install from source:

git clone https://github.com/pfrederiksen/arccos-api.git
cd arccos-api
pip install -e .

Requires Python >= 3.11. Dependencies: requests, click, rich.

CLI

Quick start

arccos login       # authenticate and save credentials
arccos rounds      # your recent rounds
arccos handicap    # handicap breakdown
arccos clubs       # smart club distances

Commands

Command Description
arccos login Authenticate and securely cache credentials
arccos rounds List recent rounds with date, score, +/-, course name
arccos round <id> Hole-by-hole detail (score, putts, FIR, GIR) with totals
arccos handicap Handicap breakdown by category (overall, driving, approach, etc.)
arccos clubs Smart club distances with make/model, range, and shot count
arccos bests All-time personal bests (lowest score, longest drive, etc.)
arccos overview Performance summary — scoring avg + handicap breakdown
arccos scoring Scoring trend with visual bar chart
arccos compare <a> <b> Side-by-side hole-by-hole round comparison
arccos courses List courses you've played (or --search to filter)
arccos pace Pace of play analysis by course (color-coded)
arccos stats Strokes gained analysis (defaults to latest round)
arccos stats --dashboard Strokes gained analysis from the current dashboard endpoint
arccos tour-analytics Tour analytics summary/facet data
arccos trends Handicap trend chart over recent rounds
arccos club-shots <id> Shot history for a specific club
arccos shot-dispersion [id] Shot dispersion for the bag or a specific club
arccos up-and-down Scramble / strokes-to-get-down stats
arccos hole-image <course> <hole> Hole feature metadata and dashboard image URLs
arccos export Export rounds to JSON, CSV, or NDJSON (--detail for hole data)
arccos completions <shell> Generate bash/zsh/fish completion script
arccos logout Clear cached credentials
arccos doctor Check configuration, credentials, and API connectivity

Every command supports --json for raw JSON output and --help for usage info.

Usage examples

# Rounds
arccos rounds                         # last 20 rounds (with +/- and course names)
arccos rounds -n 50                   # last 50
arccos rounds --after 2025-01-01      # filter by date
arccos rounds --course "pebble"       # filter by course name (substring)
arccos rounds --json                  # raw JSON

# Round detail
arccos round 12345678                 # hole-by-hole breakdown

# Handicap
arccos handicap                       # category breakdown
arccos handicap --history             # revision history

# Club distances
arccos clubs                          # active clubs with make/model
arccos clubs --after 2025-01-01       # distances from this year only

# Performance
arccos bests                          # all-time personal bests
arccos overview                       # scoring avg + handicap breakdown
arccos scoring                        # scoring trend with bar chart
arccos stats --dashboard              # dashboard SGA, same endpoint as web app
arccos stats --dashboard --latest     # dashboard SGA for your latest round
arccos trends                         # handicap trend chart
arccos up-and-down                    # scramble stats
arccos tour-analytics --facet driving # tour analytics by facet
arccos tour-analytics --summary       # tour analytics summary

# Compare rounds
arccos compare 12345678 12345679      # side-by-side hole comparison

# Courses
arccos courses                        # all courses played
arccos courses --search "torrey"      # filter by name or city

# Club detail
arccos club-shots 1                   # shot history for club ID 1
arccos shot-dispersion                # bag-level dispersion data
arccos shot-dispersion 1 --json       # raw dispersion for club ID 1

# Hole imagery metadata
arccos hole-image 10769 7 -v 11       # image + metadata URLs and hole features

# Shell completions
eval "$(arccos completions bash)"     # enable tab completion
eval "$(arccos completions zsh)"      # for zsh

# Pace of play
arccos pace                           # all rounds, slowest courses first
arccos pace -n 20                     # last 20 rounds only

# Export
arccos export -f csv -o rounds.csv    # export to CSV file
arccos export --detail                # include hole-by-hole data
arccos export -f json                 # dump JSON to stdout
arccos export -f ndjson               # newline-delimited JSON

Example output

$ arccos clubs
            Smart Club Distances
╭──────┬──────────────────┬───────┬─────────┬──────────┬───────╮
│ Club │ Model            │ Smart │ Longest │    Range │ Shots │
├──────┼──────────────────┼───────┼─────────┼──────────┼───────┤
│ Dr   │ Example Driver   │  252y │    291y │ 245–263y │   312 │
│ 3w   │ Example Fairway  │  228y │    248y │ 220–235y │    87 │
│ 5w   │ Example Fairway  │  208y │    231y │ 200–215y │   143 │
│ 4h   │ Example Hybrid   │  195y │    214y │ 188–202y │    61 │
│ 6i   │ Example Iron     │  172y │    190y │ 165–179y │    94 │
│ 7i   │ Example Iron     │  160y │    178y │ 153–167y │   118 │
│ 8i   │ Example Iron     │  148y │    165y │ 141–155y │   105 │
│ 9i   │ Example Iron     │  136y │    152y │ 130–142y │    97 │
│ Pw   │ Example Wedge    │  124y │    140y │ 118–130y │    82 │
│ 50   │ Vokey SM10       │  108y │    125y │ 102–114y │    76 │
│ 54   │ Vokey SM10       │   88y │    105y │  82–94y  │   201 │
│ 58   │ Vokey SM10       │   64y │     88y │  58–70y  │   168 │
╰──────┴──────────────────┴───────┴─────────┴──────────┴───────╯

$ arccos round 12345678
╭─── Round 12345678 ────╮
│ Date:   2026-01-15    │
│ Course: Example GC    │
│ Score:  79 (+7)       │
│ Holes:  18            │
╰───────────────────────╯
            Hole-by-Hole
╭──────┬───────┬───────┬─────┬─────╮
│ Hole │ Score │ Putts │ FIR │ GIR │
├──────┼───────┼───────┼─────┼─────┤
│    1 │     4 │     2 │  T  │  T  │
│    2 │     5 │     2 │  F  │  F  │
│    3 │     3 │     1 │     │  T  │
│  ... │   ... │   ... │ ... │ ... │
├──────┼───────┼───────┼─────┼─────┤
│  Tot │    79 │    31 │     │     │
╰──────┴───────┴───────┴─────┴─────╯

$ arccos handicap
  Handicap Breakdown
╭────────────┬───────╮
│ Category   │   HCP │
├────────────┼───────┤
│ Overall    │ -12.4 │
│ Driving    │ -15.1 │
│ Approach   │ -18.7 │
│ Short Game │ -14.3 │
│ Putting    │  -6.2 │
╰────────────┴───────╯

$ arccos pace -n 10
Pace of Play — 10 rounds across 6 courses   Overall avg: 4h 22m

                  By Course (slowest first)
╭───┬──────────┬───────────────────────┬────────╮
│   │ Avg Time │ Course                │ Rounds │
├───┼──────────┼───────────────────────┼────────┤
│ ● │   5h 10m │ Example Golf Club A    │      2 │
│ ● │   4h 45m │ Example Golf Club B    │      3 │
│ ● │   3h 50m │ Example Golf Club C    │      2 │
│ ● │   3h 35m │ Chambers Bay          │      1 │
╰───┴──────────┴───────────────────────┴────────╯

Environment variables

Skip the login prompt by setting:

export ARCCOS_EMAIL="you@example.com"
export ARCCOS_PASSWORD="your_password"
arccos rounds

Other environment variables:

export ARCCOS_TIMEOUT=30       # request timeout in seconds (default: 15)
export ARCCOS_LOG_LEVEL=DEBUG  # enable debug logging (DEBUG, INFO, WARNING)
export ARCCOS_PROFILE=work     # select a named credential profile
export ARCCOS_KEYRING=true     # use the operating-system keyring

Security note: Environment variables may be visible in process listings (ps) and shell history. Prefer arccos login for interactive use.

Python Library

from arccos import ArccosClient

client = ArccosClient(email="you@example.com", password="your_password")
# Credentials are cached in the platform config directory and refresh silently.

# Rounds
rounds = client.rounds.list(limit=10)
for r in rounds:
    print(f"{r['startTime'][:10]}  score={r['noOfShots']}  {r.get('courseName', '')}")

# Round detail (includes embedded hole-by-hole data)
rd = client.rounds.get(rounds[0]["roundId"])
for hole in rd["holes"]:
    print(f"  Hole {hole['holeId']}: {hole['noOfShots']} shots, {hole['putts']} putts")

# Handicap breakdown
hcp = client.handicap.current()
print(f"Overall: {hcp['userHcp']:.1f}")
print(f"Driving: {hcp['driveHcp']:.1f}")

# Club distances (returns clubId as bag slot — see bag API for name mapping)
for club in client.clubs.smart_distances():
    dist = club["smartDistance"]["distance"]
    print(f"  Club {club['clubId']}: {dist:.0f}y")

# Bag configuration (maps clubId → clubType + make/model)
profile = client.profile()
bag = client.clubs.bag(str(profile["bagId"]))
for club in bag["clubs"]:
    if club.get("isDeleted") != "T":
        print(f"  {club['clubMakeOther']} {club['clubModelOther']}")

# Current dashboard club/SGA analytics endpoints
club_inventory = client.clubs.list()
shot_dispersion = client.clubs.shot_dispersion()
dashboard_sga = client.stats.dashboard_analysis(goal_hcp=5, no_of_rounds=20)
player_profile = client.stats.player_profile()
tour_summary = client.stats.tour_analytics_summary()

# Course / hole imagery metadata
hole_features = client.courses.hole_features(10769, 7, version=11)
image_url = client.courses.hole_image_url(10769, 7, 11, "2026-07")
metadata_url = client.courses.hole_metadata_url(10769, 7, 11, "2026-07")

# Courses played
for course in client.courses.played():
    print(f"  {course.get('name', course['courseId'])}")

# Pace of play analysis
pace = client.rounds.pace_of_play()
print(f"Overall avg: {pace['overall_avg_display']}")
for c in pace["course_averages"][:5]:
    print(f"  {c['avg_display']}  {c['course']}")

# Personal bests
bests = client.stats.personal_bests()

# Iterate ALL rounds (auto-pagination)
for r in client.rounds.iter_all():
    print(r["roundId"], r["noOfShots"])

# Course search
results = client.courses.search("Example Golf Club")

API Reference

Full OpenAPI 3.1 spec: docs/openapi.yaml

Authentication

All auth calls go to https://authentication.arccosgolf.com.

These are the only non-GET Arccos interactions in this project. They obtain an access key and JWT; they do not write golf or account data.

Step Endpoint Body Returns
1. Get access key POST /accessKeys {"email", "password", "signedInByFacebook": "F"} {"userId", "accessKey", "secret"}
2. Get JWT POST /tokens {"userId", "accessKey"} {"userId", "token"}

The JWT expires in ~3 hours. The accessKey is valid for ~180 days. Refresh by calling POST /tokens again.

Endpoints

All data calls go to https://api.arccosgolf.com with Authorization: Bearer <token>.

The data client enforces GET only and exposes no POST, PUT, PATCH, or DELETE methods.

Resource Method Path
User profile GET /users/{userId} (includes bagId, bags[])
User details GET /users/{userId}/details
Bag / clubs GET /users/{userId}/bags/{bagId} (club config with make/model)
Club inventory GET /v6/users/{userId}/clubs
Rounds GET /users/{userId}/rounds?offSet=0&limit=200&roundType=flagship
Round detail GET /users/{userId}/rounds/{roundId} (includes holes[] with shots[])
Handicap GET /users/{userId}/handicaps/latest
Handicap history GET /users/{userId}/handicaps?rounds=20
Smart distances GET /v4/clubs/user/{userId}/smart-distances
Shot dispersion GET /v3/user/{userId}/clubs/dispersion
Club shot dispersion GET /v3/user/{userId}/clubs/{clubId}/dispersion
Courses played GET /users/{userId}/coursesPlayed
Course metadata GET /courses/{courseId}?courseVersion=1
Hole feature metadata GET /courses/{courseId}/holes/{holeId}?courseVersion=1
Course search GET /v2/courses?search={query}
Club shots GET /users/{userId}/bags/{bagId}/clubs/{clubId}/shots
Dashboard SGA GET /sga/getDashboardAnalysis/{userId}
SGA player profile GET /sga/playerProfile/{userId}
Tour analytics GET /users/{userId}/tourAnalytics
Tour analytics summary GET /users/{userId}/tourAnalyticsSummary
Tour analytics ranked GET /users/{userId}/tourAnalyticsRanked
Personal bests GET /users/{userId}/personalBests?tags=allTimeBest
Strokes to get down GET /v2/sga/strokes-to-get-down

Key data structures

Round (from GET /users/{id}/rounds/{roundId}):

{
  "roundId": 12345678,
  "courseId": 12450,
  "courseVersion": 4,
  "startTime": "2026-01-15T15:30:00.000000Z",
  "endTime": "2026-01-15T20:15:00.000000Z",
  "noOfShots": 79,
  "noOfHoles": 18,
  "holes": [
    {
      "holeId": 1, "noOfShots": 4, "putts": 2,
      "isGir": "T", "isFairWay": "T",
      "shots": [{"clubId": 1, "clubType": 1, "distance": 255.0}]
    }
  ]
}

Smart distance (from GET /v4/clubs/user/{id}/smart-distances):

{
  "clubId": 1,
  "smartDistance": {"distance": 252.3, "unit": "yd"},
  "longest": {"distance": 291.0, "unit": "yd"},
  "range": {"low": 245.0, "high": 263.0, "unit": "yd"},
  "usage": {"count": 312}
}

Bag club (from GET /users/{id}/bags/{bagId}):

{
  "clubId": 1, "clubType": 1,
  "clubMakeOther": "Example", "clubModelOther": "Model 1",
  "isDeleted": "F"
}

clubId is a user-specific bag slot. Resolve to a display name via: bag's clubType → standard name (1=Dr, 2=3w, 3=5w, 5=4i, ..., 11=Pw, 12=Putter, 43=Aw, 53=56°).

Development

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

pytest                  # tests with coverage (87%+, 203 tests)
ruff check .            # lint
mypy arccos/            # type check
openapi-spec-validator docs/openapi.yaml

Coverage report: htmlcov/index.html. Minimum threshold: 80% (configured in pyproject.toml). The suite includes sanitized response-contract fixtures so upstream schema drift is caught without making live API calls.

Security

  • Data access is read-only: the client only sends GET requests to api.arccosgolf.com. The only POST requests are the required login/token-refresh calls to authentication.arccosgolf.com; no golf data is created, changed, or deleted.
  • Credentials are cached in the platform configuration directory (mode 0600 — owner-only read/write). Existing ~/.arccos_creds.json files migrate automatically. Named profiles are available through ARCCOS_PROFILE or --profile.
  • Optional OS-keyring storage is available with pip install 'arccos-api[keyring]' and ARCCOS_KEYRING=true (or --keyring for login/logout/doctor).
  • All API communication uses HTTPS with TLS certificate verification.
  • arccos logout removes the local credential file but does not revoke server-side tokens. If you suspect your credentials were compromised, change your Arccos password.
  • The export command restricts output paths to your home directory or current working directory.
  • Security issues should be reported privately as described in SECURITY.md.

Disclaimer

Not affiliated with, endorsed by, or connected to Arccos Golf LLC. Use your own account credentials only. This project is for personal data access and research.

MIT License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

arccos_api-0.5.2.tar.gz (67.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arccos_api-0.5.2-py3-none-any.whl (56.7 kB view details)

Uploaded Python 3

File details

Details for the file arccos_api-0.5.2.tar.gz.

File metadata

  • Download URL: arccos_api-0.5.2.tar.gz
  • Upload date:
  • Size: 67.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for arccos_api-0.5.2.tar.gz
Algorithm Hash digest
SHA256 521bfc344ec57a8c250c364267e22edf3bd13147b2cb852d58a606ab5778517d
MD5 7d8d9af84a48f8bf57abb4a7edbe8e57
BLAKE2b-256 46b2e957d6e0e5a1f1dfab8bd23b5f77464c291cdde2fc0f374c37c6261093c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for arccos_api-0.5.2.tar.gz:

Publisher: release.yml on pfrederiksen/arccos-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file arccos_api-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: arccos_api-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 56.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for arccos_api-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 8badb9a66ea681340d90e2a0ebcef301197e2d622880225d94d6597c7e43b6bb
MD5 347ec421cab780852cf29068fb0e9d07
BLAKE2b-256 fe04590ded3331d29481471b64faa5a634e08edfa361d0643c8cd1d72b13ba73

See more details on using hashes here.

Provenance

The following attestation bundles were made for arccos_api-0.5.2-py3-none-any.whl:

Publisher: release.yml on pfrederiksen/arccos-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.4

2 files

0.5.3

2 files

This release

0.5.2 This release

2 files

0.5.1

2 files

0.5.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page