# Platforms

Platforms resource for the GunSpec SDK. Wraps `/v1/platforms`: the families (`ak-100`, `ar-15`) whose interface rows every member inherits. One row on a platform reaches every firearm that belongs to it, which is the lever behind most computed fits. Studio.

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

## client.platforms.list()

`GET /v1/platforms`

Auth: API key required  
Tier: Studio+

Every platform with its member count. Answers 304.

### 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[].id` | string | Slug of the platform. |
| `data[].name` | string | Display name, as the maker writes it. |
| `data[].description` | string \| null | Prose summary of the record, where one has been written. |
| `data[].memberCount` | integer | How many firearms belong to the platform. |

```json
{
  "success": true,
  "data": [
    {
      "id": "ak-100",
      "name": "AK-100 series (AK-74M pattern)",
      "description": "AK-74M and its export family.",
      "memberCount": 11
    }
  ]
}
```

### 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/platforms' \
  --header 'X-API-Key: your_key'
```

## client.platforms.get()

`GET /v1/platforms/{id}`

Auth: API key required  
Tier: Studio+

A platform's interface rows and members. Answers 304.

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Platform slug |

### 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.id` | string | Slug of the platform. |
| `data.name` | string | Display name, as the maker writes it. |
| `data.description` | string \| null | Prose summary of the record, where one has been written. |
| `data.interfaces` | object[] | The mount interfaces resolved for this firearm, own rows first, then inherited. |
| `data.interfaces[].position` | string | Where on the firearm the interface sits: `muzzle`, `rear`, `top`, `bottom`. |
| `data.interfaces[].standardId` | string | Id of the interface standard, kind-prefixed, e.g. `thread:1/2x28`. Ids are never renamed; new spellings become aliases. |
| `data.interfaces[].name` | string | Display name, as the maker writes it. |
| `data.interfaces[].kind` | string | What the asset is: `silhouette`, `render`, `photo`, `schematic`, `model`. `/v1/firearms/{id}/media/{selector}` addresses an asset by this. |
| `data.interfaces[].confidence` | number | How well evidenced this row is, 0 to 1. **A minimum, not an average**: an inferred row caps every fit computed through it, and `min_confidence` on the endpoint hides rows below a threshold. |
| `data.interfaces[].notes` | string \| null | Free-text notes that do not belong in a specific field. |
| `data.members` | object[] | The firearms belonging to this platform, which inherit its default interfaces. |
| `data.members[].id` | string | Slug of the firearm. |
| `data.members[].name` | string | Display name, as the maker writes it. |

```json
{
  "success": true,
  "data": {
    "id": "ak-100",
    "name": "AK-100 series (AK-74M pattern)",
    "description": "AK-74M and its export family.",
    "interfaces": [
      {
        "position": "rear",
        "standardId": "stock:ak-100-folder",
        "name": "AK-100 series polymer side-folder trunnion (AK-74M pattern)",
        "kind": "stock_mount",
        "confidence": 1,
        "notes": null
      }
    ],
    "members": [
      {
        "id": "ak-74m",
        "name": "AK-74M"
      }
    ]
  }
}
```

### Errors

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

### Example

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