GolfAPI Driver Catalog — API Reference
Unlisted reference page for evaluation. Version 2026-09-08. Last verified against production 2026-09-17.
This page contains no credentials. An API key is supplied separately by whoever gave you this link. Every endpoint except /health requires one.
What this API is
A catalog of golf drivers from major manufacturers. It exists to answer two questions: which club is this, and what exact build did the manufacturer offer.
It is deliberately positioned for programmatic consumers, including AI agents, rather than for a human browsing a website.
Product tiers
| Tier | Status | What it adds |
|---|---|---|
| Basic | Public, live now | Club identity and core specs: name, manufacturer, family, lofts, hands, head volume, adjustability flags, release date, intro price. |
| Club-builder | Gated, selected keys | Exact-build depth: variants, hosel systems and settings, stock shafts, grips, weights, head geometry, compatibility. |
| Full | Not built | Complete catalog plus insight fields, undefined pending customer demand. |
The omission rule
This is the central data contract and it matters when you evaluate the responses. An absent field means "not verified." It never means zero, unknown, or pending. A value only appears after a human has signed off on it. Nulls and placeholders are not used, so you will see objects with fields simply missing rather than set to null.
A real 0 or false is always returned, never dropped. "adjustable_weight": false means verified as not adjustable.
What is actually in the catalog right now
Measured against production on 2026-09-17:
| Metric | Value |
|---|---|
| Driver objects | 42 |
| Manufacturers | 7 — Callaway (11), TaylorMade (8), Cobra (8), Titleist (4), PING (4), PXG (4), Srixon (3) |
| Model years present | 2025, 2026 |
| Model years absent | 2020–2024 |
| Mini-drivers | Routed and entitled, catalog small |
The stated launch target is complete major-manufacturer coverage from model year 2020 to present. The live catalog does not meet that yet. Records exist internally for roughly 101 drivers; 42 have passed sign-off and are published. The rest are omitted rather than shipped unverified.
Connecting
| Base URL | https://clubapi.golfapi.dev |
|---|---|
| Auth | Authorization: Bearer <key> |
| Format | JSON. No request body on any endpoint; everything is query parameters. |
curl -H "Authorization: Bearer $KEY" \
"https://clubapi.golfapi.dev/drivers?manufacturer=ping&limit=2"
There is no discovery surface. / returns 404. There is no /openapi.json, no /docs, no .well-known descriptor, and no hypermedia index. This page is the only description of the API's shape. If you are evaluating how well this API serves automated consumers, that fact is evidence.
Routes
| Route | Auth | Expected |
|---|---|---|
GET /health | none | 200 {"ok":true,"db":"ok"} |
GET /drivers | required | 200 list |
GET /drivers/{slug|id} | required | 200 single object |
GET /mini-drivers | required | 200 list |
GET /mini-drivers/{slug|id} | required | 200 single object |
GET /hosel-systems | required | 403 without Club-builder entitlement |
GET /weight-systems | required | 503 — routed, catalog unpublished |
GET /shafts | required | 503 — routed, catalog unpublished |
GET /grips | required | 503 — routed, catalog unpublished |
A 503 on the equipment routes is the designed pre-release state, not an outage. The route exists and the key is entitled; the catalog has not been published.
Query parameters
List routes
| Parameter | Accepts | Notes |
|---|---|---|
limit | 1–100 | Default 20. Out of range is 400. |
cursor | opaque string | Use page.next from the previous response unchanged. Edited cursors are 400. |
view | basic | expanded | Default basic. Asking for expanded without the Club-builder entitlement is 403, not a thinned document. |
fields | comma-separated | Restricts returned fields. An unknown name for the active view is 400. |
manufacturer | slug | e.g. ping, callaway, taylormade, titleist, cobra, pxg, srixon |
family | slug | e.g. g440 |
profile | draw | neutral | low-spin | |
hand | rh | lh | |
loft | number | Degrees, one decimal place allowed. |
adjustable_hosel | true | false | Literal strings only. |
adjustable_weight | true | false | Literal strings only. |
weight_system | fixed | movable | interchangeable | |
released_after | ISO date | YYYY-MM-DD |
released_before | ISO date | YYYY-MM-DD |
q | 1–200 chars | Free-text search. Control characters rejected. |
hosel_system | hos_ + 26 chars | Filter by hosel system id. |
Detail routes
| Parameter | Accepts | Notes |
|---|---|---|
view | basic | expanded | Defaults to expanded here. A key without Club-builder silently receives the basic representation; explicitly asking for expanded is 403. |
fields | comma-separated | Validated against the active view. |
variants | all | rh | lh | loft | Default all. Club-builder depth only. |
Response shapes
List — wrapped
GET /drivers?limit=1&manufacturer=ping
{
"data": [
{
"id": "clb_01M21MDKGYVNWAT3EFJ9XCE0PC",
"slug": "g440-k-driver",
"name": "G440 K Driver",
"manufacturer": { "slug": "ping", "name": "PING" },
"family": { "slug": "g440", "name": "G440" },
"profile": "neutral",
"released": "2026-01-29",
"lofts_deg": [9, 10.5, 12],
"hands": ["rh", "lh"],
"volume_cc": 460,
"adjustable_hosel": true,
"adjustable_weight": true,
"weight_system": "movable",
"intro_price": [
{ "market": "US", "msrp_minor": 70500, "currency": "USD" }
],
"url": "https://clubapi.golfapi.dev/drivers/g440-k-driver"
}
],
"page": { "limit": 1, "has_more": true, "next": "cur_eyJyIjoi..." }
}
Prices are minor units. 70500 with "currency": "USD" is $705.00.
Detail — not wrapped
GET /drivers/g440-k-driver
{
"id": "clb_01M21MDKGYVNWAT3EFJ9XCE0PC",
"slug": "g440-k-driver",
...
"url": "https://clubapi.golfapi.dev/drivers/g440-k-driver"
}
The detail route returns the object at the top level. It is not wrapped in data the way list responses are. Clients must handle both shapes.
Basic vs Club-builder depth
The same club, fetched with two different keys:
| Key | Fields returned |
|---|---|
| Basic | id, slug, name, manufacturer, family, profile, released, lofts_deg, hands, volume_cc, adjustable_hosel, adjustable_weight, weight_system, intro_price, url |
| Club-builder | the above plus head, hosel, notes, _links, variant detail |
Errors
Every error uses the same envelope, with a request_id and an optional param naming the offending input.
{
"error": {
"type": "invalid_request",
"message": "Invalid value for 'limit': must be between 1 and 100.",
"status": 400,
"request_id": "req_01M2R68V6A5K9J0A5HQWJB2N2P",
"param": "limit"
}
}
| Status | When |
|---|---|
400 | Unknown fields name, limit out of range, malformed or edited cursor, invalid enum or date. |
401 | Missing or unknown key. |
403 | Known key without entitlement to the resource or to Club-builder depth. |
404 | Single fetch of an unknown record. An empty list is 200 with "data": [], never 404. |
503 | Routed resource whose catalog is unpublished, or a version pin requesting an unreleased catalog. |
Observed error messages: "Unknown field 'nope' for view 'basic'." · "Invalid cursor. Use the 'next' value from a previous page unchanged." · "No driver with slug 'no-such-club'."
Versioning, caching, redirects
- Every response carries a
Golfapi-Versionheader. Current:2026-09-08. - Send
Golfapi-Version: <date>to pin. Pinning to a date whose catalog is unreleased returns503. - Responses carry an
ETag. A matchingIf-None-Matchreturns304. - A changed slug returns
301to the current path. Anidnever redirects — ids are stable, slugs are not. - Rate limit: 60 requests per window. Check
ratelimit-limitandratelimit-remainingresponse headers.
Known gaps
Stated plainly so evaluation focuses on what matters rather than rediscovering these:
- No model years 2020–2024. The catalog starts at 2025.
- 42 of roughly 101 known driver records are published.
- No OpenAPI document, no
/index, no machine-readable discovery of any kind. /shafts,/grips,/weight-systemsreturn503by design; catalogs unpublished./hosel-systemsrequires the Club-builder entitlement.- List responses are wrapped in
data; detail responses are not.
Testing etiquette
This is a live production service on a small budget. Probe correctness and edge cases freely; keep total requests modest and do not load-test, benchmark throughput, or run concurrent floods. Rate limiting will stop you at 60 per window regardless.