---
name: turagolf
version: 1.0.0
description: Golf round tracking and handicap API. Log scorecards, calculate handicap index, manage tee time bookings, and track course stats.
homepage: https://www.turagolf.com
metadata: {"category":"sports","api_base":"https://www.turagolf.com/api/v1"}
---

# TuraGolf

**Golf data via API. Rounds, handicaps, and tee times.**

Log rounds hole by hole, calculate handicap index automatically, manage tee time bookings, and access course data. The complete data layer for golf apps. Part of Tura Cloud. Authentication uses TuraLogin API keys (Bearer token).

## Skill Files

| File | URL |
|------|-----|
| **SKILL.md** (this file) | `https://www.turagolf.com/SKILL.md` |
| **AGENTS.md** | `https://www.turagolf.com/AGENTS.md` |
| **API.md** | `https://www.turagolf.com/API.md` |
| **QUICKSTART.md** | `https://www.turagolf.com/QUICKSTART.md` |
| **skill.json** (metadata) | `https://www.turagolf.com/skill.json` |

**Base URL:** `https://www.turagolf.com/api/v1`

**Authentication:** `Authorization: Bearer <API_KEY>` — Use TuraLogin API keys from https://www.turalogin.com/dashboard/keys

---

## Overview

TuraGolf is a golf data API:

✅ **Round logging** — Full scorecard per hole with fairways, putts, and penalties  
✅ **Handicap** — Automatic handicap index calculation from round history  
✅ **Tee times** — Create and manage bookings by course, date, and party size  
✅ **Stats** — Fairways hit, GIR, putts per round, scoring average  

You handle:
- Course database and hole layouts (or use your own)
- Frontend scorekeeping UI
- User identity (use TuraLogin)
- Payments for tee time booking (use TuraShop)

---

## Quick Start

### 1. Get Your API Key

TuraGolf uses **TuraLogin API keys**. Get one at https://www.turalogin.com/dashboard/keys

### 2. Log a Round

```bash
curl -X POST https://www.turagolf.com/api/v1/golf/rounds \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_123",
    "courseId": "course_456",
    "tee": "white",
    "scores": [
      { "hole": 1, "par": 4, "score": 5, "fairway": true, "gir": false, "putts": 2 },
      { "hole": 2, "par": 3, "score": 3, "fairway": null, "gir": true, "putts": 1 }
    ]
  }'
```

**Response:**
```json
{
  "id": "round_abc123",
  "userId": "user_123",
  "courseId": "course_456",
  "totalScore": 87,
  "scoreToPar": 15,
  "differentialUsed": 14.2,
  "fairwaysHitPct": 61.5,
  "girPct": 33.3,
  "avgPutts": 1.8,
  "createdAt": "2026-02-22T10:00:00Z"
}
```

### 3. Get Current Handicap

```bash
curl "https://www.turagolf.com/api/v1/golf/handicap/user_123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

---

## Full API Reference

### POST /api/v1/golf/rounds

Log a golf round.

**Request Body:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `userId` | string | Yes | Golfer's user ID |
| `courseId` | string | Yes | Course ID |
| `tee` | string | No | Tee color/name played |
| `scores` | array | Yes | Per-hole score objects |
| `playedAt` | string | No | ISO 8601 date (defaults to now) |
| `weather` | string | No | `sunny`, `cloudy`, `windy`, `rainy` |

**Hole score object:**

| Field | Type | Description |
|-------|------|-------------|
| `hole` | number | Hole number (1–18) |
| `par` | number | Hole par |
| `score` | number | Gross score |
| `fairway` | boolean | Fairway hit (null for par 3s) |
| `gir` | boolean | Green in regulation |
| `putts` | number | Number of putts |
| `penalties` | number | Penalty strokes |

---

### GET /api/v1/golf/rounds

List a user's round history.

**Query Parameters:** `userId` (required), `courseId`, `from`, `to` (YYYY-MM-DD), `limit`, `cursor`

---

### GET /api/v1/golf/handicap/:userId

Get a user's current handicap index.

**Success Response (200):**
```json
{
  "userId": "user_123",
  "handicapIndex": 14.2,
  "trend": -0.8,
  "roundsUsed": 20,
  "lastUpdated": "2026-02-22T10:00:00Z"
}
```

---

### GET /api/v1/golf/stats/:userId

Get aggregate stats for a user.

**Success Response (200):**
```json
{
  "userId": "user_123",
  "roundsPlayed": 48,
  "scoringAverage": 87.3,
  "fairwaysHitPct": 58.2,
  "girPct": 31.4,
  "avgPutts": 1.9,
  "bestRound": { "score": 79, "date": "2026-01-15", "courseId": "course_456" }
}
```

---

### GET /api/v1/golf/courses

Search available courses.

**Query Parameters:** `q` (name search), `lat`, `lon`, `radius` (km), `limit`

---

### GET /api/v1/golf/courses/:id

Get course details including holes and slope/rating by tee.

---

### POST /api/v1/golf/teetimes

Book a tee time.

**Request Body:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `courseId` | string | Yes | Course to book at |
| `requestedAt` | string | Yes | Requested datetime (ISO 8601) |
| `players` | number | Yes | Party size (1–4) |
| `userId` | string | Yes | Booking user |

**Success Response (201):**
```json
{
  "id": "tt_abc123",
  "courseId": "course_456",
  "confirmedAt": "2026-03-01T08:00:00Z",
  "players": 4,
  "status": "confirmed"
}
```

---

### GET /api/v1/golf/teetimes

List a user's tee time bookings.

**Query Parameters:** `userId`, `from`, `to`, `status` (`confirmed`, `cancelled`, `completed`)

---

### DELETE /api/v1/golf/teetimes/:id

Cancel a tee time booking.

---

## Framework Examples

### Next.js (App Router)

```typescript
// app/api/golf/rounds/route.ts
export async function POST(request: Request) {
  const body = await request.json();

  const res = await fetch('https://www.turagolf.com/api/v1/golf/rounds', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.TURAGOLF_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });

  return Response.json(await res.json(), { status: res.status });
}

// app/api/golf/handicap/[userId]/route.ts
export async function GET(
  _request: Request,
  { params }: { params: { userId: string } }
) {
  const res = await fetch(
    `https://www.turagolf.com/api/v1/golf/handicap/${params.userId}`,
    { headers: { 'Authorization': `Bearer ${process.env.TURAGOLF_API_KEY}` } }
  );
  return Response.json(await res.json());
}
```

---

## Error Codes

| Status | Error | Description |
|--------|-------|-------------|
| 400 | `userId is required` | Missing user ID |
| 400 | `courseId is required` | Missing course ID |
| 400 | `scores must have at least 1 hole` | Empty scores array |
| 400 | `Invalid hole number` | Hole outside 1–18 range |
| 401 | `Unauthorized` | Missing or invalid API key |
| 404 | `Course not found` | Invalid course ID |
| 404 | `Tee time not found` | Invalid booking ID |
| 409 | `Tee time unavailable` | Slot already booked |
| 429 | `Too many requests` | Rate limit exceeded |

---

## Support & Resources

- 🌐 Website: https://www.turagolf.com
- 🔑 API Keys: https://www.turalogin.com/dashboard/keys
