# Releases

New firearm models, each with the dates it was announced and first read, its alternate names and the sources that name it

Source: https://docs.gunspec.io/en/api/releases

## List new firearm models

`GET /v1/releases`

Auth: API key required  
Tier: Explorer+

Returns new firearm models, newest announcement first, each with the date it was announced, the date GunSpec first read it, its alternate names and the pages that name it. A model appears only after research has read a source a reader can cite (the maker, a standards body, a government, a reference work or the press) and quoted the words that name it; a headline alone never makes a row. `status` says whether the catalog holds a record yet (`catalogued`, with `catalogueId`) or not (`announced`). Filter by day with `since` and `until`: they apply to `announcedAt`, or to the day GunSpec first read the model with `order=consumed`. A model with no dated source counts from the day it was first read.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | no | Page number, from 1 to 10,000 |
| `per_page` | integer | no | Items per page (max 100) |
| `since` | string | no | Only models on or after this day (`YYYY-MM-DD`) |
| `until` | string | no | Only models on or before this day (`YYYY-MM-DD`) |
| `maker` | string | no | Filter by catalog manufacturer id |
| `status` | string | no | Filter by whether the catalog holds a record yet |
| `q` | string | no | Search the model name, its alternate names and the maker |
| `order` | string | no | Sort and date-filter by the announcement date, or by the day GunSpec first read the model |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object[] | A new firearm model: its name and alternate names, the dates it was announced and first read, and the sources that name it. |
| `data[].id` | string | Stable id of the release row. |
| `data[].slug` | string | The id the catalog gives the model once it holds a record. Informational: it can change if research settles a different name, so key on `id`. |
| `data[].name` | string | The model's name as the maker writes it, settled by research from a page that states it. |
| `data[].alternateNames` | string[] | Other names the sources give the model. Each appears on a page research read; none is inferred. |
| `data[].manufacturer` | object \| null | The maker. `id` is the catalog manufacturer id, or null when the catalog holds no record of the maker yet. |
| `data[].manufacturer.id` | string \| null | Catalog manufacturer id. |
| `data[].manufacturer.name` | string | Maker name. |
| `data[].status` | string | Whether the catalog holds a record for the model yet. |
| `data[].catalogueId` | string \| null | The firearm id once `status` is `catalogued`, for `GET /v1/firearms/{id}`. Null before. |
| `data[].announcedAt` | string \| null | The date (`YYYY-MM-DD`) of the earliest source a reader can cite that names the model. Null when no source carried a date. |
| `data[].releasedAt` | string \| null | When a source says the model ships or goes on sale, at the precision it gave: `YYYY`, `YYYY-MM` or `YYYY-MM-DD`. Null when no source states a date. "Spring 2027" is not a date and is never turned into one. |
| `data[].releasedPrecision` | string \| null | How much of `releasedAt` the source gave. |
| `data[].firstSeenAt` | string | When GunSpec first read the model (UTC): the date we consumed it. Always present. |
| `data[].updatedAt` | string | When the row last changed (UTC). |
| `data[].bestSourceKind` | string \| null | The strongest kind among `sources`, strongest first: the maker's own page, a standards body, a government, a reference work, then press. |
| `data[].sources` | object[] | The pages that name the model, oldest first. Every release has at least one of a citable kind. |
| `data[].sources[].url` | string | A page that names the model. Open it to check the claim. |
| `data[].sources[].kind` | string | What kind of page it is (`SourceKind`). |
| `data[].sources[].publisher` | string \| null | Who published it, when known. |
| `data[].sources[].publishedAt` | string \| null | The page's own date (`YYYY-MM-DD`), when it carried one. |
| `pagination.page` | number | Current page number |
| `pagination.per_page` | number | Items per page |
| `pagination.total` | number | Total matching records (Builder and above) |

```json
{
  "success": true,
  "data": [
    {
      "id": "7c3f2a90-5e1b-4d8a-9b6c-2f4e8a1d0c35",
      "slug": "northfield-arms-nf-9-compact",
      "name": "Northfield Arms NF-9 Compact",
      "alternateNames": [
        "NF-9C"
      ],
      "manufacturer": {
        "id": "northfield-arms",
        "name": "Northfield Arms"
      },
      "status": "announced",
      "catalogueId": null,
      "announcedAt": "2026-09-18",
      "releasedAt": "2026-11",
      "releasedPrecision": "month",
      "firstSeenAt": "2026-09-19T04:15:02Z",
      "updatedAt": "2026-09-21T09:30:11Z",
      "bestSourceKind": "manufacturer",
      "sources": [
        {
          "url": "https://www.example.com/news/northfield-nf-9-compact",
          "kind": "manufacturer",
          "publisher": "Northfield Arms",
          "publishedAt": "2026-09-18"
        }
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "per_page": 20,
    "total": 42,
    "totalPages": 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/releases?since=2026-09-01' \
  --header 'X-API-Key: your_key'
```
