# My Support

Create and manage support tickets for billing questions, bug reports, feature requests, and general inquiries. Full threaded replies are supported. Available on Builder tier and above.

Source: https://docs.gunspec.io/en/api/me-support

## List Tickets

`GET /v1/me/support`

Auth: API key required  
Tier: Explorer+

Returns your support tickets, newest first. **Requires a paid plan (Builder or above).**

### 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) |
| `status` | string | no | Filter by ticket status |
| `sort` | string | no | Sort field |
| `order` | string | no | Sort order |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | SupportTicket[] | One page of results |
| `data[].id` | string | Opaque ticket id. |
| `data[].subject` | string | One-line summary of the issue. |
| `data[].description` | string | Prose summary of the record, where one has been written. |
| `data[].status` | TicketStatus | Lifecycle of a support ticket. `waiting` means we are waiting on the customer. |
| `data[].priority` | TicketPriority | Support ticket priority. |
| `data[].category` | string \| null | What the ticket is about: `billing`, `technical`, `data_quality`, `feature_request`, `other`. |
| `data[].reply_count` | integer | How many replies the thread holds. |
| `data[].created_at` | string | When the ticket was opened, ISO 8601. |
| `data[].updated_at` | string | When the ticket last changed, ISO 8601. |
| `data[].closed_at` | string \| null | When it was closed, or null while it is open. |
| `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": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
      "subject": "Cannot generate an API key",
      "description": "string",
      "status": "open",
      "priority": "low",
      "category": "technical",
      "reply_count": 2,
      "created_at": "2026-08-23T02:00:00.000Z",
      "updated_at": "string",
      "closed_at": null
    }
  ],
  "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 |

### Notes

- Requires **Builder** tier or higher.
- Tickets are sorted by created_at descending.

### Example

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

## Create Ticket

`POST /v1/me/support`

Auth: API key required  
Tier: Explorer+

Opens a support ticket against your account. **Requires a paid plan (Builder or above).**

### Request body (application/json)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `subject` | string | yes | One-line summary of the issue. |
| `description` | string | yes | Prose summary of the record, where one has been written. |
| `category` | string | no | What the ticket is about. Not a firearm or attachment category. |
| `priority` | string | no | Triage priority you are asking for. Staff may change it. |

```json
{
  "subject": "Bulk firearms endpoint returns 500 on large per_page",
  "description": "When I set per_page=100 on GET /v1/firearms, I consistently receive a 500 Internal Server Error. Per page values of 50 or below work fine.",
  "priority": "high",
  "category": "technical"
}
```

### Response 201 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | SupportTicket | The response payload |
| `data.id` | string | Opaque ticket id. |
| `data.subject` | string | One-line summary of the issue. |
| `data.description` | string | Prose summary of the record, where one has been written. |
| `data.status` | TicketStatus | Lifecycle of a support ticket. `waiting` means we are waiting on the customer. |
| `data.priority` | TicketPriority | Support ticket priority. |
| `data.category` | string \| null | What the ticket is about: `billing`, `technical`, `data_quality`, `feature_request`, `other`. |
| `data.reply_count` | integer | How many replies the thread holds. |
| `data.created_at` | string | When the ticket was opened, ISO 8601. |
| `data.updated_at` | string | When the ticket last changed, ISO 8601. |
| `data.closed_at` | string \| null | When it was closed, or null while it is open. |

```json
{
  "success": true,
  "data": {
    "id": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
    "subject": "Cannot generate an API key",
    "description": "string",
    "status": "open",
    "priority": "low",
    "category": "technical",
    "reply_count": 2,
    "created_at": "2026-08-23T02:00:00.000Z",
    "updated_at": "string",
    "closed_at": null
  }
}
```

### Errors

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

### Notes

- Requires **Builder** tier or higher.
- Valid priorities: `low`, `normal`, `high`, `urgent`. Valid categories: `billing`, `technical`, `data_quality`, `feature_request`, `other`.
- High-priority tickets are reviewed within 1 business day.

### Example

```bash
curl --request POST \
  --url 'https://api.gunspec.io/v1/me/support' \
  --header 'X-API-Key: your_key' \
  --header 'Content-Type: application/json' \
  --data '
{
  "subject": "Cannot generate an API key",
  "description": "The button does nothing when I click it.",
  "category": "technical",
  "priority": "normal"
}
'
```

## Get Ticket

`GET /v1/me/support/{ticketId}`

Auth: API key required  
Tier: Explorer+

Returns one of your tickets with its replies and attachments. **Requires a paid plan (Builder or above).**

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ticketId` | string | yes | Support ticket id |

### Response 200 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | SupportTicket | The response payload |
| `data.id` | string | Opaque ticket id. |
| `data.subject` | string | One-line summary of the issue. |
| `data.description` | string | Prose summary of the record, where one has been written. |
| `data.status` | TicketStatus | Lifecycle of a support ticket. `waiting` means we are waiting on the customer. |
| `data.priority` | TicketPriority | Support ticket priority. |
| `data.category` | string \| null | What the ticket is about: `billing`, `technical`, `data_quality`, `feature_request`, `other`. |
| `data.reply_count` | integer | How many replies the thread holds. |
| `data.created_at` | string | When the ticket was opened, ISO 8601. |
| `data.updated_at` | string | When the ticket last changed, ISO 8601. |
| `data.closed_at` | string \| null | When it was closed, or null while it is open. |
| `data.replies` | object[] | Every reply on the ticket in the order it was written, staff-internal notes excluded. |
| `data.replies[].id` | integer | Numeric id of the reply. |
| `data.replies[].ticket_id` | string | Id of the ticket. |
| `data.replies[].user_id` | string | Who wrote it: the customer or a staff member. |
| `data.replies[].message` | string | The reply body. |
| `data.replies[].created_at` | string | When the reply was recorded, ISO 8601 UTC. |
| `data.attachments` | object[] | Files attached to the ticket or to one of its replies. |
| `data.attachments[].id` | integer | Numeric id of the attachment. |
| `data.attachments[].ticket_id` | string | Id of the ticket the file belongs to. |
| `data.attachments[].reply_id` | integer \| null | The reply the file was attached to, or null when it was attached to the ticket itself. |
| `data.attachments[].user_id` | string | Who uploaded it. |
| `data.attachments[].file_name` | string | The name the file was uploaded with. |
| `data.attachments[].file_key` | string | Storage key; download through the ticket attachment endpoint, never by constructing a URL from this. |
| `data.attachments[].file_size` | integer | Bytes. |
| `data.attachments[].mime_type` | string | Media type as detected at upload. |
| `data.attachments[].created_at` | string | When the file was attached, ISO 8601 UTC. |

```json
{
  "success": true,
  "data": {
    "id": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
    "subject": "Cannot generate an API key",
    "description": "string",
    "status": "open",
    "priority": "low",
    "category": "technical",
    "reply_count": 2,
    "created_at": "2026-08-23T02:00:00.000Z",
    "updated_at": "string",
    "closed_at": null,
    "replies": [
      {
        "id": 12,
        "ticket_id": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
        "user_id": "u_...",
        "message": "Still happening on the latest build.",
        "created_at": "2026-08-23T02:00:00.000Z"
      }
    ],
    "attachments": [
      {
        "id": 3,
        "ticket_id": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
        "reply_id": null,
        "user_id": "u_...",
        "file_name": "screenshot.png",
        "file_key": "tickets/d3f1c2a0/3.png",
        "file_size": 48213,
        "mime_type": "image/png",
        "created_at": "2026-08-23T02:00:00.000Z"
      }
    ]
  }
}
```

### 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 |

### Notes

- Requires **Builder** tier or higher.
- You can only retrieve tickets created by your own API key.
- Replies are sorted by created_at ascending (oldest first).

### Example

```bash
curl --request GET \
  --url 'https://api.gunspec.io/v1/me/support/d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10' \
  --header 'X-API-Key: your_key'
```

## Reply to Ticket

`POST /v1/me/support/{ticketId}/replies`

Auth: API key required  
Tier: Explorer+

Adds a reply to one of your tickets. **Requires a paid plan (Builder or above).**

### Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `ticketId` | string | yes | Support ticket id |

### Request body (application/json)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `message` | string | yes | The reply body. Plain text. |

```json
{
  "message": "Thanks for the update! The fix is working perfectly on my end."
}
```

### Response 201 (application/json)

| Field | Type | Description |
| --- | --- | --- |
| `data` | object | The response payload. |
| `data.id` | integer | Numeric id of the reply. |
| `data.ticket_id` | string | Id of the ticket the reply was added to. |
| `data.message` | string | The reply body, as sent. |
| `data.created_at` | string | When the reply was recorded, ISO 8601 UTC. |

```json
{
  "success": true,
  "data": {
    "id": 12,
    "ticket_id": "d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10",
    "message": "Still happening on the latest build.",
    "created_at": "2026-08-23T02:00:00.000Z"
  }
}
```

### 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 |
| 413 | `PAYLOAD_TOO_LARGE` | Request body too large |
| 429 | `RATE_LIMITED` | Rate limit exceeded |
| 500 | `INTERNAL_ERROR` | Unexpected server error |

### Notes

- Requires **Builder** tier or higher.
- Replies cannot be added to tickets with status `closed`.
- You can only reply to tickets created by your own API key.

### Example

```bash
curl --request POST \
  --url 'https://api.gunspec.io/v1/me/support/d3f1c2a0-5b7e-4c1a-9f2d-6e8b3a4c7d10/replies' \
  --header 'X-API-Key: your_key' \
  --header 'Content-Type: application/json' \
  --data '
{
  "message": "Still happening on the latest build."
}
'
```
