> This page is optimized for agents. Use the linked Markdown pages and llms.txt indexes for related API content.

# Catalog coverage

> Published record counts by resource, manufacturer, release year and field presence, limited to the club resources the key can access. Requires any club resource entitlement. Query parameters return 400. Returns 503 when no build is published. Supports ETag revalidation.

- Product: Coverage
- Section: coverage
- Snapshot: Current
- Method: `GET`
- Path: `/coverage`
- Availability: generally-available

## Execute with curl

```bash
curl -H "Authorization: Bearer $GOLFDEV_API_KEY" "https://api.golfapi.dev/coverage"
```

## Execute with JavaScript

```javascript
const response = await fetch(`https://api.golfapi.dev/coverage`, {
  headers: { Authorization: `Bearer ${process.env.GOLFDEV_API_KEY}` },
});
const body = await response.json();
```

## Execute with Python

```python
import os
import requests

response = requests.get(
    f"https://api.golfapi.dev/coverage",
    headers={"Authorization": f"Bearer {os.environ['GOLFDEV_API_KEY']}"},
    timeout=10,
)
response.raise_for_status()
body = response.json()
```

## Responses

### Response `200`

Category: success  

Published catalog counts.

#### `application/json`

##### Generated example

```json
{
  "build": "build",
  "published_at": "published_at",
  "catalog_complete": true,
  "resources": [
    {
      "resource": "drivers",
      "version": "version",
      "complete": true,
      "records": 0,
      "years": {},
      "fields": {},
      "manufacturers": [
        {
          "slug": "slug",
          "name": "name",
          "records": 1,
          "years": {},
          "fields": {}
        }
      ]
    }
  ],
  "note": "note"
}
```

##### Schema

###### Coverage

Type: `Coverage`  

Published record counts by resource, manufacturer, release year and field presence. Counts describe the published build; an empty result does not establish that a product does not exist.

###### `build`

Type: `string`  
Required: yes  

###### `published_at`

Type: `string`  
Format: `date-time`  
Required: yes  

###### `catalog_complete`

Type: `boolean`  
Required: yes  

Whether the catalog covers its launch scope. False. Every count in this response describes published records, so a search miss, an empty page and a 404 are statements about this build and not about what exists.

###### `note`

Type: `string`  
Required: no  

Plain-language restatement of what the counts do and do not establish.

###### `resources`

Type: `ResourceCoverage[]`  
Required: yes  

Only club types accessible to this key.

###### ResourceCoverage

Type: `ResourceCoverage`  

Published counts for one club type. The years map is keyed by release_year. Counts cover the resources accessible to the key.

###### `resource`

Type: `string`  
Required: yes  
Allowed values: `drivers`, `mini-drivers`, `fairway-woods`, `hybrids`, `irons`, `wedges`, `putters`  

###### `version`

Type: `string`  
Format: `date`  
Required: yes  

###### `complete`

Type: `boolean`  
Required: yes  

Whether every eligible head in this club type's launch scope is published. False, and never computed from the counts below: a populated cell is not evidence that its eligible head set is exhaustive. It turns true only on a separate owner decision that establishes an exhaustive denominator.

###### `records`

Type: `number`  
Required: yes  

###### `years`

Type: `object`  
Required: yes  

Counts keyed by name. Every key the served shape defines for this club type is present, including the ones at 0: a field that is defined and carried by nothing is exactly what a caller needs to know before building on it, and omitting the key would make that indistinguishable from 'not a field'. A field the club type does not define is absent rather than 0.

###### `fields`

Type: `object`  
Required: yes  

Counts keyed by name. Every key the served shape defines for this club type is present, including the ones at 0: a field that is defined and carried by nothing is exactly what a caller needs to know before building on it, and omitting the key would make that indistinguishable from 'not a field'. A field the club type does not define is absent rather than 0.

###### `manufacturers`

Type: `ManufacturerCoverage[]`  
Required: yes  

Largest first, ties broken on slug, so the order is stable between builds.

###### ManufacturerCoverage

Type: `ManufacturerCoverage`  

One manufacturer's row of the grid.

###### `slug`

Type: `string`  
Required: yes  

###### `name`

Type: `string`  
Required: yes  

###### `records`

Type: `number`  
Required: yes  

###### `years`

Type: `object`  
Required: yes  

Records this manufacturer published, by `release_year`. A year with none is absent from this map.

###### `fields`

Type: `object`  
Required: yes  

How many of this manufacturer's records carry each field. The keys are the Core document's top-level fields plus `hosel_summary.adjustable`, counted from the Core document; fields defined but carried by nothing appear at 0.

### Response `304`

Category: redirect  

Unchanged representation, no response body. Quota refunded after response.

### Response `400`

Category: client-error  

Invalid recognized input or projected field.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `401`

Category: client-error  

Missing, malformed, unknown, or revoked key.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `403`

Category: client-error  

Resource/capability not granted.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `405`

Category: client-error  

A routed path reached by a method other than GET or OPTIONS.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `429`

Category: client-error  

Rate limit reached. 60 requests per 60-second wall-clock window by default; RateLimit-Limit carries this key's actual cap. Honor Retry-After, which equals RateLimit-Reset.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `500`

Category: server-error  

Server fault.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

### Response `503`

Category: server-error  

Required representation or schema unavailable; honor Retry-After.

#### `application/json`

##### Generated example

```json
{
  "error": {
    "type": "invalid_request",
    "message": "message",
    "status": 400,
    "request_id": "request_id",
    "param": "param"
  }
}
```

##### Schema

###### Error

Type: `Error`  

###### `error`

Type: `object`  
Required: yes  

###### `type`

Type: `string`  
Required: yes  
Allowed values: `invalid_request`, `invalid_auth`, `forbidden`, `not_found`, `rate_limited`, `method_not_allowed`, `server_error`, `service_unavailable`, `account_inactive`, `quota_exceeded`  

###### `message`

Type: `string`  
Required: yes  

###### `status`

Type: `number`  
Required: yes  
Allowed values: `400`, `401`, `403`, `404`, `405`, `429`, `500`, `503`  

###### `request_id`

Type: `string`  
Required: yes  

###### `param`

Type: `string`  
Required: no  

## Related representations

- [Human documentation](/api/coverage/methods/get/)
- [curl Markdown](/api/coverage/curl/methods/get.md)
- [JavaScript Markdown](/api/coverage/javascript/methods/get.md)
- [Python Markdown](/api/coverage/python/methods/get.md)
- [product llms.txt](/api/coverage/llms.txt)
