# Stats

Resource class for interacting with the GunSpec Statistics API. Wraps all `/v1/stats` endpoints. Instantiated internally by the GunSpec client and exposed as `client.stats`.

Source: https://docs.gunspec.io/en/sdk/stats

## client.stats.summary()

`GET /v1/stats/summary`

Auth: API key required  
Tier: Explorer+

Get a high-level summary of the database.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `If-None-Match` | string | no | The `ETag` from a previous response. If the body would be byte-identical, the API answers `304 Not Modified` with no body. A 304 counts toward the per-minute rate limit but not the daily request allowance. |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.total_firearms` | integer | Firearms in the catalog. |
| `data.total_manufacturers` | integer | Manufacturers in the catalog. Counts rows, so it exceeds the number of makers with a catalogued firearm. |
| `data.total_calibers` | integer | Cartridges in the catalog. |
| `data.countries_of_origin` | integer | Distinct countries of origin across the catalog. |
| `data.avg_confidence` | number | Mean `data_confidence` across the catalog, as a percentage rather than the 0-1 the per-record field uses. |
| `data.total_variants` | integer | Firearms that are a variant of another, meaning those carrying a `parentFirearmId`. |

```json
{
  "success": true,
  "data": {
    "total_firearms": 8630,
    "total_manufacturers": 1112,
    "total_calibers": 605,
    "countries_of_origin": 92,
    "avg_confidence": 74,
    "total_variants": 1350
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/summary' \
  --header 'X-API-Key: your_key'
```

## client.stats.productionStatus()

`GET /v1/stats/production-status`

Auth: API key required  
Tier: Explorer+

Get firearm counts grouped by production status.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].status` | string \| null | Production status, one of `in_production`, `discontinued`, `out_of_production`, `in_service`, `limited_production`, `prototype`. Discontinued records are kept deliberately: a rifle built in 2004 wears parts nobody sells today. |
| `data[].count` | integer | How many records fall in this bucket. |

```json
{
  "success": true,
  "data": [
    {
      "status": "in_production",
      "count": 640
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/production-status' \
  --header 'X-API-Key: your_key'
```

## client.stats.fieldCoverage()

`GET /v1/stats/field-coverage`

Auth: API key required  
Tier: Explorer+

Get field coverage statistics across the database. Shows the percentage of firearms that have data for each field, useful for assessing data completeness.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].field` | string | Which column the row is about, named as the database names it. |
| `data[].percentage` | number | Share of records, 0 to 100. |

```json
{
  "success": true,
  "data": [
    {
      "field": "weight_empty_g",
      "percentage": 94
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/field-coverage' \
  --header 'X-API-Key: your_key'
```

## client.stats.popularCalibers()

`GET /v1/stats/calibers/popular`

Auth: API key required  
Tier: Explorer+

Get the most popular calibers by firearm count.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | no | How many to return |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].id` | string | Slug of the cartridge. |
| `data[].name` | string | Display name, as the maker writes it. |
| `data[].nato_designation` | string \| null | NATO designation where the cartridge has one. Null otherwise. |
| `data[].firearm_count` | integer | How many catalogued firearms chamber it. |

```json
{
  "success": true,
  "data": [
    {
      "id": "9x19mm-parabellum",
      "name": "9x19mm Parabellum",
      "nato_designation": "9mm NATO",
      "firearm_count": 1140
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/calibers/popular?limit=20' \
  --header 'X-API-Key: your_key'
```

## client.stats.prolificManufacturers()

`GET /v1/stats/manufacturers/prolific`

Auth: API key required  
Tier: Explorer+

Get the most prolific manufacturers by firearm count.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | no | How many to return |
| `category` | string | no | Restrict to a category slug |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].id` | string | Slug of the manufacturer. |
| `data[].name` | string | Display name, as the maker writes it. |
| `data[].country_code` | string \| null | ISO 3166-1 alpha-2 code of where they are based. |
| `data[].firearm_count` | integer | How many catalogued firearms they make. |

```json
{
  "success": true,
  "data": [
    {
      "id": "smith-wesson",
      "name": "Smith & Wesson",
      "country_code": "US",
      "firearm_count": 356
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/manufacturers/prolific?limit=20&category=pistol' \
  --header 'X-API-Key: your_key'
```

## client.stats.byCategory()

`GET /v1/stats/by-category`

Auth: API key required  
Tier: Explorer+

Get firearm counts grouped by category.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].id` | string | Slug of the category. |
| `data[].name` | string | Display name, as the maker writes it. |
| `data[].firearm_count` | integer | How many catalogued firearms are in it. |
| `data[].avg_weight_g` | number \| null | Mean unloaded weight in grams across the category, over the firearms that record one. |
| `data[].avg_magazine_capacity` | number \| null | Mean magazine capacity across the category, over the firearms that record one. |
| `data[].avg_barrel_length_mm` | number \| null | Mean barrel length in millimetres across the category, over the firearms that record one. |

```json
{
  "success": true,
  "data": [
    {
      "id": "pistol",
      "name": "Pistol",
      "firearm_count": 3922,
      "avg_weight_g": 816.37,
      "avg_magazine_capacity": 10.94,
      "avg_barrel_length_mm": 111.07
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/by-category' \
  --header 'X-API-Key: your_key'
```

## client.stats.byEra()

`GET /v1/stats/by-era`

Auth: API key required  
Tier: Studio+

Get firearm statistics for a specific decade/era.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `decade` | string | yes | Decade to report on, formatted like "1990s" |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.firearm_count` | integer | Firearms introduced in the decade. |
| `data.avg_weight_g` | number \| null | Mean unloaded weight in grams, over those that record one. |
| `data.avg_magazine_capacity` | number \| null | Mean magazine capacity, over those that record one. |
| `data.avg_barrel_length_mm` | number \| null | Mean barrel length in millimetres, over those that record one. |
| `data.earliest_year` | integer \| null | Earliest introduction year inside the decade that any record carries. |
| `data.latest_year` | integer \| null | Latest introduction year inside the decade that any record carries. |

```json
{
  "success": true,
  "data": {
    "firearm_count": 487,
    "avg_weight_g": 2183.4,
    "avg_magazine_capacity": 14.2,
    "avg_barrel_length_mm": 304.9,
    "earliest_year": 1990,
    "latest_year": 1999
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/by-era?decade=1990s' \
  --header 'X-API-Key: your_key'
```

## client.stats.materials()

`GET /v1/stats/materials`

Auth: API key required  
Tier: Studio+

Get statistics about materials used across all firearms.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.frame` | object[] | Frame materials, and how many firearms use each. |
| `data.frame[].material` | string | The material as recorded on the firearm. |
| `data.frame[].count` | integer | How many records fall in this bucket. |
| `data.slide` | object[] | Slide materials, and how many firearms use each. |
| `data.slide[].material` | string | The material as recorded on the firearm. |
| `data.slide[].count` | integer | How many records fall in this bucket. |
| `data.barrel` | object[] | Barrel materials, and how many firearms use each. |
| `data.barrel[].material` | string | The material as recorded on the firearm. |
| `data.barrel[].count` | integer | How many records fall in this bucket. |
| `data.stock` | object[] | Stock materials, and how many firearms use each. |
| `data.stock[].material` | string | The material as recorded on the firearm. |
| `data.stock[].count` | integer | How many records fall in this bucket. |

```json
{
  "success": true,
  "data": {
    "frame": [
      {
        "material": "Polymer",
        "count": 2841
      }
    ],
    "slide": [
      {
        "material": "Polymer",
        "count": 2841
      }
    ],
    "barrel": [
      {
        "material": "Polymer",
        "count": 2841
      }
    ],
    "stock": [
      {
        "material": "Polymer",
        "count": 2841
      }
    ]
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/materials' \
  --header 'X-API-Key: your_key'
```

## client.stats.adoptionByCountry()

`GET /v1/stats/adoption/by-country`

Auth: API key required  
Tier: Studio+

Get firearm adoption statistics for a specific country.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | yes | ISO 3166-1 alpha-2 country code |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].id` | integer | Numeric id of the adoption record itself, not of the firearm. |
| `data[].user_name` | string \| null | The organisation that adopted the firearm. |
| `data[].user_type` | string \| null | Kind of operator: one of `military`, `law_enforcement`, `civilian`, `paramilitary`, `special_forces`, `private_security`, `training`. |
| `data[].adopted_year` | integer \| null | Year the operator adopted it. Null where the date is unrecorded. |
| `data[].designation` | string \| null | Military or standards designation for the load, e.g. `M882`. |
| `data[].firearm_id` | string | Slug of the adopted firearm. |
| `data[].firearm_name` | string | Display name of the firearm. |

```json
{
  "success": true,
  "data": [
    {
      "id": 412,
      "user_name": "Australian Army",
      "user_type": "military",
      "adopted_year": 1988,
      "designation": "F88 Austeyr",
      "firearm_id": "steyr-aug",
      "firearm_name": "Steyr AUG"
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/adoption/by-country?code=AU' \
  --header 'X-API-Key: your_key'
```

## client.stats.adoptionByType()

`GET /v1/stats/adoption/by-type`

Auth: API key required  
Tier: Studio+

Get firearm adoption statistics by usage type.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `type` | string | yes | Operator type |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].firearm_id` | string | Slug of the adopted firearm. |
| `data[].firearm_name` | string | Display name of the firearm. |
| `data[].adoption_count` | integer | How many operators of this type adopted it. |
| `data[].countries` | string[] | ISO 3166-1 alpha-2 codes of the countries those operators belong to. |

```json
{
  "success": true,
  "data": [
    {
      "firearm_id": "makarov-pm",
      "firearm_name": "Makarov PM",
      "adoption_count": 36,
      "countries": [
        "SU"
      ]
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/adoption/by-type?type=military' \
  --header 'X-API-Key: your_key'
```

## client.stats.actionTypes()

`GET /v1/stats/action-types`

Auth: API key required  
Tier: Explorer+

Get firearm counts grouped by action type.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `category` | string | no | Restrict to a category slug |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].action_type` | string \| null | The action as stored, and the value to send as `action_type` when filtering. |
| `data[].count` | integer | How many records fall in this bucket. |

```json
{
  "success": true,
  "data": [
    {
      "action_type": "short_recoil",
      "count": 2812
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/action-types?category=rifle' \
  --header 'X-API-Key: your_key'
```

## client.stats.featureFrequency()

`GET /v1/stats/feature-frequency`

Auth: API key required  
Tier: Builder+

Get feature frequency statistics across the database.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `category` | string | no | Restrict to a category slug |
| `limit` | integer | no | How many to return |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].feature` | string | The feature as stored, and the value to send as `feature` to /v1/firearms/by-feature. |
| `data[].count` | integer | How many records fall in this bucket. |

```json
{
  "success": true,
  "data": [
    {
      "feature": "threaded-barrel",
      "count": 163
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/feature-frequency?category=pistol&limit=50' \
  --header 'X-API-Key: your_key'
```

## client.stats.caliberPopularityByEra()

`GET /v1/stats/caliber-popularity-by-era`

Auth: API key required  
Tier: Studio+

Get caliber popularity trends across historical eras.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from_decade` | string | no | Earliest decade, formatted like "1940s" |
| `to_decade` | string | no | Latest decade, formatted like "2020s" |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | The response payload. |
| `data[].decade` | string | The decade this row covers, e.g. `1940s`. |
| `data[].calibers` | object[] | The cartridges chambered by firearms introduced in this decade. |
| `data[].calibers[].caliberId` | string | Slug of the cartridge. Resolve against `/v1/calibers/{id}`. |
| `data[].calibers[].caliberName` | string | Display name of the cartridge. |
| `data[].calibers[].firearmCount` | integer | How many firearms this row covers. |

```json
{
  "success": true,
  "data": [
    {
      "decade": "1940s",
      "calibers": [
        {
          "caliberId": "9x19mm-parabellum",
          "caliberName": "9x19mm Parabellum",
          "firearmCount": 42
        }
      ]
    }
  ]
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/caliber-popularity-by-era?from_decade=1940s&to_decade=2020s' \
  --header 'X-API-Key: your_key'
```

## client.stats.catalogCoverage()

`GET /v1/stats/catalog-coverage`

Auth: API key required  
Tier: Explorer+

Get catalog completeness percentages. Reports what share of firearms have a line-art image, core specifications filled, at least one caliber mapped, and a recorded weight. Computed live.

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.total` | integer | Total records matching the query across every page. |
| `data.images` | number | Percentage of firearms carrying at least one image. |
| `data.specifications` | number | Percentage of firearms carrying at least one recorded specification. |
| `data.caliber` | number | Percentage of firearms with at least one caliber recorded. |
| `data.weight` | number | Percentage of firearms with an unloaded weight recorded. |

```json
{
  "success": true,
  "data": {
    "total": 8630,
    "images": 28,
    "specifications": 95.9,
    "caliber": 82.4,
    "weight": 94.3
  }
}
```

### Errors

| Status | Code | Message |
| --- | --- | --- |
| 400 | `VALIDATION_ERROR` | Validation error |
| 401 | `UNAUTHORIZED` | API key required |
| 403 | `FORBIDDEN` | Valid key, not permitted |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/stats/catalog-coverage' \
  --header 'X-API-Key: your_key'
```
