# Tickets endpoints (Admin API)

> 32 FeatherPanel Admin API endpoints from admin/tickets.php: methods, paths, auth, permissions, rate limits, parameters and responses.

Source: https://featherpanel.com/docs/api/reference/admin/tickets/

Defined in [`backend/app/routes/admin/tickets.php`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php). Authentication used here: **Admin**. Read [Authentication](https://featherpanel.com/docs/api/authentication/) for how to send credentials and [Rate limits and errors](https://featherpanel.com/docs/api/rate-limits-and-errors/) for the response envelope.

Paths, methods, permissions and rate limits come from the route file. Summaries, parameters and response codes come from the OpenAPI annotations on the controllers; endpoints without annotations show only what the route file declares.

## Endpoints

### GET `/api/admin/tickets`

- Auth: Admin
- Permission: `admin.tickets.view`
- Route name: `admin-tickets`
- Controller: [`TicketsController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L33)

**Get all tickets** Retrieve a paginated list of all tickets with optional filters and search functionality.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number for pagination |
| `limit` | query | integer | no | Number of records per page |
| `search` | query | string | no | Search term to filter tickets by title or description |
| `user_uuid` | query | string (uuid) | no | Filter by user UUID |
| `server_id` | query | integer | no | Filter by server ID |
| `category_id` | query | integer | no | Filter by category ID |
| `status_id` | query | integer | no | Filter by status ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `tickets` | Ticket\[\] |  |
| `pagination` | TicketPagination |  |
| `search` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Tickets retrieved successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions

### PUT `/api/admin/tickets`

- Auth: Admin
- Permission: `admin.tickets.create`
- Route name: `admin-tickets-create`
- Controller: [`TicketsController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L43)

**Create new ticket** Create a new ticket. Admins can create tickets on behalf of users.

Request body: [`TicketCreate`](https://featherpanel.com/docs/api/schemas/#schema-ticketcreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `user_uuid` | string (uuid) | yes | User UUID who is creating the ticket |
| `server_id` | integer | no | Server ID if ticket is related to a server |
| `category_id` | integer | yes | Category ID |
| `priority_id` | integer | yes | Priority ID |
| `status_id` | integer | yes | Status ID |
| `title` | string | yes | Ticket title |
| `description` | string | yes | Ticket description |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `ticket_id` | integer | Created ticket ID |
| `ticket_uuid` | string (uuid) | Created ticket UUID |

```bash
curl -X PUT "$PANEL_URL/api/admin/tickets" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"user_uuid":"","server_id":0,"category_id":0,"priority_id":0,"status_id":0,"title":"","description":""}'
```

Plugin events: [`featherpanel:ticket:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-created)

Responses: `201` Ticket created successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error

### POST `/api/admin/tickets/categories/upload-icon`

- Auth: Admin
- Permission: `admin.ticket_categories.create`
- Route name: `admin-ticket-categories-upload-icon`
- Controller: [`TicketCategoriesController::uploadIcon`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L56)

**Upload icon for ticket category** Upload an icon image file for ticket categories. Supports JPG, PNG, GIF, and WebP formats with a maximum size of 5MB.

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `icon` | string (binary) | yes | Icon image file (JPG, PNG, GIF, WebP, max 5MB) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `url` | string | Public URL of the uploaded icon |
| `filename` | string | Filename of the uploaded icon |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/categories/upload-icon" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -F "icon=@./file"
```

Responses: `201` Icon uploaded successfully · `400` Bad request - No file provided, invalid file type, or file too large · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error - Failed to save file

### GET `/api/admin/tickets/categories`

- Auth: Admin
- Permission: `admin.ticket_categories.view`
- Route name: `admin-ticket-categories`
- Controller: [`TicketCategoriesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L67)

**Get all ticket categories** Retrieve a paginated list of all ticket categories with optional search functionality.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number for pagination |
| `limit` | query | integer | no | Number of records per page |
| `search` | query | string | no | Search term to filter categories |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `categories` | TicketCategory\[\] |  |
| `pagination` | TicketCategoryPagination |  |
| `search` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/categories" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Categories retrieved successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions

### GET `/api/admin/tickets/categories/{id}`

- Auth: Admin
- Permission: `admin.ticket_categories.view`
- Route name: `admin-ticket-categories-show`
- Controller: [`TicketCategoriesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L77)

**Get ticket category by ID** Retrieve a specific ticket category by its ID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Category ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `category` | TicketCategory |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/categories/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Category retrieved successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Category not found

### PUT `/api/admin/tickets/categories`

- Auth: Admin
- Permission: `admin.ticket_categories.create`
- Route name: `admin-ticket-categories-create`
- Controller: [`TicketCategoriesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L92)

**Create new ticket category** Create a new ticket category with comprehensive validation.

Request body: [`TicketCategoryCreate`](https://featherpanel.com/docs/api/schemas/#schema-ticketcategorycreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Category name |
| `icon` | string | no | Category icon |
| `color` | string | no | Category color |
| `support_email` | string | no | Support email for this category |
| `open_hours` | string | no | Open hours |
| `description` | string | no | Category description |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `category_id` | integer | Created category ID |

```bash
curl -X PUT "$PANEL_URL/api/admin/tickets/categories" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","icon":"","color":"","support_email":"","open_hours":"","description":""}'
```

Plugin events: [`featherpanel:ticket:category:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-category-created)

Responses: `201` Category created successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error

### PATCH `/api/admin/tickets/categories/{id}`

- Auth: Admin
- Permission: `admin.ticket_categories.edit`
- Route name: `admin-ticket-categories-update`
- Controller: [`TicketCategoriesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L103)

**Update ticket category** Update an existing ticket category with comprehensive validation.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Category ID |

Request body: [`TicketCategoryUpdate`](https://featherpanel.com/docs/api/schemas/#schema-ticketcategoryupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no | Category name |
| `icon` | string | no | Category icon |
| `color` | string | no | Category color |
| `support_email` | string | no | Support email for this category |
| `open_hours` | string | no | Open hours |
| `description` | string | no | Category description |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X PATCH "$PANEL_URL/api/admin/tickets/categories/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","icon":"","color":"","support_email":"","open_hours":"","description":""}'
```

Plugin events: [`featherpanel:ticket:category:updated`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-category-updated)

Responses: `200` Category updated successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Category not found · `500` Internal server error

### DELETE `/api/admin/tickets/categories/{id}`

- Auth: Admin
- Permission: `admin.ticket_categories.delete`
- Route name: `admin-ticket-categories-delete`
- Controller: [`TicketCategoriesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketCategoriesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L119)

**Delete ticket category** Permanently delete a ticket category.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Category ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/categories/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:category:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-category-deleted)

Responses: `200` Category deleted successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Category not found · `409` Conflict - Cannot delete (tickets exist) · `500` Internal server error

### GET `/api/admin/tickets/priorities`

- Auth: Admin
- Permission: `admin.ticket_priorities.view`
- Route name: `admin-ticket-priorities`
- Controller: [`TicketPrioritiesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketPrioritiesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L137)

**Get all ticket priorities** Retrieve a paginated list of all ticket priorities with optional search functionality.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number for pagination |
| `limit` | query | integer | no | Number of records per page |
| `search` | query | string | no | Search term to filter priorities |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `priorities` | TicketPriority\[\] |  |
| `pagination` | TicketPriorityPagination |  |
| `search` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/priorities" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Priorities retrieved successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions

### GET `/api/admin/tickets/priorities/{id}`

- Auth: Admin
- Permission: `admin.ticket_priorities.view`
- Route name: `admin-ticket-priorities-show`
- Controller: [`TicketPrioritiesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketPrioritiesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L147)

**Get ticket priority by ID** Retrieve a specific ticket priority by its ID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Priority ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `priority` | TicketPriority |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/priorities/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Priority retrieved successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Priority not found

### PUT `/api/admin/tickets/priorities`

- Auth: Admin
- Permission: `admin.ticket_priorities.create`
- Route name: `admin-ticket-priorities-create`
- Controller: [`TicketPrioritiesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketPrioritiesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L162)

**Create new ticket priority** Create a new ticket priority.

Request body: [`TicketPriorityCreate`](https://featherpanel.com/docs/api/schemas/#schema-ticketprioritycreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Priority name |
| `color` | string | no | Priority color |
| `sort_order` | integer | no | Display order (lower appears first) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `priority_id` | integer | Created priority ID |

```bash
curl -X PUT "$PANEL_URL/api/admin/tickets/priorities" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","color":"","sort_order":0}'
```

Plugin events: [`featherpanel:ticket:priority:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-priority-created)

Responses: `201` Priority created successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error

### PATCH `/api/admin/tickets/priorities/{id}`

- Auth: Admin
- Permission: `admin.ticket_priorities.edit`
- Route name: `admin-ticket-priorities-update`
- Controller: [`TicketPrioritiesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketPrioritiesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L173)

**Update ticket priority** Update an existing ticket priority.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Priority ID |

Request body: [`TicketPriorityUpdate`](https://featherpanel.com/docs/api/schemas/#schema-ticketpriorityupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no | Priority name |
| `color` | string | no | Priority color |
| `sort_order` | integer | no | Display order (lower appears first) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X PATCH "$PANEL_URL/api/admin/tickets/priorities/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","color":"","sort_order":0}'
```

Plugin events: [`featherpanel:ticket:priority:updated`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-priority-updated)

Responses: `200` Priority updated successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Priority not found · `500` Internal server error

### DELETE `/api/admin/tickets/priorities/{id}`

- Auth: Admin
- Permission: `admin.ticket_priorities.delete`
- Route name: `admin-ticket-priorities-delete`
- Controller: [`TicketPrioritiesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketPrioritiesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L189)

**Delete ticket priority** Permanently delete a ticket priority.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Priority ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/priorities/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:priority:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-priority-deleted)

Responses: `200` Priority deleted successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Priority not found · `500` Internal server error

### GET `/api/admin/tickets/statuses`

- Auth: Admin
- Permission: `admin.ticket_statuses.view`
- Route name: `admin-ticket-statuses`
- Controller: [`TicketStatusesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketStatusesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L207)

**Get all ticket statuses** Retrieve a paginated list of all ticket statuses with optional search functionality.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number for pagination |
| `limit` | query | integer | no | Number of records per page |
| `search` | query | string | no | Search term to filter statuses |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `statuses` | TicketStatus\[\] |  |
| `pagination` | TicketStatusPagination |  |
| `search` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/statuses" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Statuses retrieved successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions

### GET `/api/admin/tickets/statuses/{id}`

- Auth: Admin
- Permission: `admin.ticket_statuses.view`
- Route name: `admin-ticket-statuses-show`
- Controller: [`TicketStatusesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketStatusesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L217)

**Get ticket status by ID** Retrieve a specific ticket status by its ID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Status ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status` | TicketStatus |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/statuses/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Status retrieved successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Status not found

### PUT `/api/admin/tickets/statuses`

- Auth: Admin
- Permission: `admin.ticket_statuses.create`
- Route name: `admin-ticket-statuses-create`
- Controller: [`TicketStatusesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketStatusesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L232)

**Create new ticket status** Create a new ticket status.

Request body: [`TicketStatusCreate`](https://featherpanel.com/docs/api/schemas/#schema-ticketstatuscreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Status name |
| `color` | string | no | Status color |
| `sort_order` | integer | no | Display order (lower appears first) |
| `is_default` | boolean | no | Assign this status to newly created tickets |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status_id` | integer | Created status ID |

```bash
curl -X PUT "$PANEL_URL/api/admin/tickets/statuses" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","color":"","sort_order":0,"is_default":false}'
```

Plugin events: [`featherpanel:ticket:status:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-created)

Responses: `201` Status created successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error

### PATCH `/api/admin/tickets/statuses/{id}`

- Auth: Admin
- Permission: `admin.ticket_statuses.edit`
- Route name: `admin-ticket-statuses-update`
- Controller: [`TicketStatusesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketStatusesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L243)

**Update ticket status** Update an existing ticket status.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Status ID |

Request body: [`TicketStatusUpdate`](https://featherpanel.com/docs/api/schemas/#schema-ticketstatusupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no | Status name |
| `color` | string | no | Status color |
| `sort_order` | integer | no | Display order (lower appears first) |
| `is_default` | boolean | no | Assign this status to newly created tickets |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X PATCH "$PANEL_URL/api/admin/tickets/statuses/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","color":"","sort_order":0,"is_default":false}'
```

Plugin events: [`featherpanel:ticket:status:updated`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-updated)

Responses: `200` Status updated successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Status not found · `500` Internal server error

### DELETE `/api/admin/tickets/statuses/{id}`

- Auth: Admin
- Permission: `admin.ticket_statuses.delete`
- Route name: `admin-ticket-statuses-delete`
- Controller: [`TicketStatusesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketStatusesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L259)

**Delete ticket status** Permanently delete a ticket status.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Status ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/statuses/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:status:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-deleted)

Responses: `200` Status deleted successfully · `400` Bad request - Invalid ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Status not found · `500` Internal server error

### GET `/api/admin/tickets/{uuid}/messages`

- Auth: Admin
- Permission: `admin.ticket_messages.view`
- Route name: `admin-ticket-messages`
- Controller: [`TicketMessagesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketMessagesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L277)

**Get all messages for a ticket** Retrieve all messages for a specific ticket by UUID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `messages` | TicketMessage\[\] |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/$UUID/messages" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Messages retrieved successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found

### GET `/api/admin/tickets/{uuid}/messages/{id}`

- Auth: Admin
- Permission: `admin.ticket_messages.view`
- Route name: `admin-ticket-messages-show`
- Controller: [`TicketMessagesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketMessagesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L292)

**Get ticket message by ID** Retrieve a specific message from a ticket.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |
| `id` | path | integer | yes | Message ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | TicketMessage |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/$UUID/messages/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Message retrieved successfully · `400` Bad request - Invalid UUID or ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket or message not found

### POST `/api/admin/tickets/{uuid}/messages`

- Auth: Admin
- Permission: `admin.ticket_messages.manage`
- Route name: `admin-ticket-messages-create`
- Controller: [`TicketMessagesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketMessagesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L312)

**Create new message for ticket** Add a new message/reply to a ticket. Support staff can add internal notes.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

Request body: [`TicketMessageCreate`](https://featherpanel.com/docs/api/schemas/#schema-ticketmessagecreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `message` | string | yes | Message content |
| `is_internal` | boolean | no | Whether this is an internal note (staff only) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message_id` | integer | Created message ID |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/$UUID/messages" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"message":"","is_internal":false}'
```

Plugin events: [`featherpanel:ticket:message:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-message-created)

Responses: `201` Message created successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found · `500` Internal server error

### PATCH `/api/admin/tickets/{uuid}/messages/{id}`

- Auth: Admin
- Permission: `admin.ticket_messages.manage`
- Route name: `admin-ticket-messages-update`
- Controller: [`TicketMessagesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketMessagesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L328)

**Update ticket message** Update an existing message in a ticket.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |
| `id` | path | integer | yes | Message ID |

Request body: [`TicketMessageUpdate`](https://featherpanel.com/docs/api/schemas/#schema-ticketmessageupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `message` | string | no | Message content |
| `is_internal` | boolean | no | Whether this is an internal note (staff only) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X PATCH "$PANEL_URL/api/admin/tickets/$UUID/messages/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"message":"","is_internal":false}'
```

Plugin events: [`featherpanel:ticket:message:updated`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-message-updated)

Responses: `200` Message updated successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket or message not found · `500` Internal server error

### DELETE `/api/admin/tickets/{uuid}/messages/{id}`

- Auth: Admin
- Permission: `admin.ticket_messages.manage`
- Route name: `admin-ticket-messages-delete`
- Controller: [`TicketMessagesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketMessagesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L349)

**Delete ticket message** Permanently delete a message from a ticket.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |
| `id` | path | integer | yes | Message ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/$UUID/messages/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:message:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-message-deleted)

Responses: `200` Message deleted successfully · `400` Bad request - Invalid UUID or ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket or message not found · `500` Internal server error

### POST `/api/admin/tickets/{uuid}/attachments`

- Auth: Admin
- Permission: `admin.ticket_attachments.manage`
- Route name: `admin-ticket-attachments-upload`
- Controller: [`TicketAttachmentsController::upload`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketAttachmentsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L372)

**Upload attachment for ticket** Upload an attachment file for a ticket. Supports various file types with a maximum size of 50MB. Files are stored under /attachments using the pattern <ticketUuid>\_tk\_<name>.<extension>.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string | yes | Ticket UUID |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `file` | string (binary) | yes | Attachment file (max 50MB) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `attachment_id` | integer | Attachment ID |
| `url` | string | Public URL of the attachment |
| `filename` | string | Stored filename |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/$UUID/attachments" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -F "file=@./file"
```

Plugin events: [`featherpanel:ticket:attachment:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-attachment-created)

Responses: `201` Attachment uploaded successfully · `400` Bad request - No file provided or invalid file · `401` Unauthorized · `403` Forbidden - Attachments disabled · `404` Ticket not found · `500` Internal server error - Failed to save file

### GET `/api/admin/tickets/{uuid}/attachments`

- Auth: Admin
- Permission: `admin.ticket_attachments.view`
- Route name: `admin-ticket-attachments-index`
- Controller: [`TicketAttachmentsController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketAttachmentsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L388)

**Get attachments for ticket** Retrieve all attachments associated with a ticket.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string | yes | Ticket UUID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `attachments` | TicketAttachment\[\] |  |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/$UUID/attachments" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Attachments retrieved successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden · `404` Ticket not found

### DELETE `/api/admin/tickets/{uuid}/attachments/{attachmentId}`

- Auth: Admin
- Permission: `admin.ticket_attachments.manage`
- Route name: `admin-ticket-attachments-delete`
- Controller: [`TicketAttachmentsController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketAttachmentsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L404)

**Delete ticket attachment** Delete a specific attachment associated with a ticket.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string | yes | Ticket UUID |
| `attachmentId` | path | integer | yes | Attachment ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/$UUID/attachments/$ATTACHMENT_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:attachment:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-attachment-deleted)

Responses: `200` Attachment deleted successfully · `400` Bad request - Invalid parameters · `401` Unauthorized · `403` Forbidden · `404` Ticket or attachment not found · `500` Internal server error

### POST `/api/admin/tickets/{uuid}/reply`

- Auth: Admin
- Permission: `admin.tickets.edit`
- Route name: `admin-tickets-reply`
- Controller: [`TicketsController::reply`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L427)

**Reply to ticket** Add a reply/message to a ticket. Support staff can add internal notes.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

Request body: [`TicketReply`](https://featherpanel.com/docs/api/schemas/#schema-ticketreply) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `message` | string | yes | Reply message |
| `is_internal` | boolean | no | Whether this is an internal note (staff only) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message_id` | integer | Created message ID |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/$UUID/reply" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"message":"","is_internal":false}'
```

Plugin events: [`featherpanel:ticket:message:created`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-message-created)

Responses: `201` Reply added successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found · `500` Internal server error

### POST `/api/admin/tickets/{uuid}/close`

- Auth: Admin
- Permission: `admin.tickets.edit`
- Route name: `admin-tickets-close`
- Controller: [`TicketsController::close`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L443)

**Close ticket** Mark a ticket as closed by setting its status to the "closed" status and updating closed\_at.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/$UUID/close" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:closed`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-closed), [`featherpanel:ticket:status:changed`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-changed)

Responses: `200` Ticket closed successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket or status not found · `500` Internal server error

### POST `/api/admin/tickets/{uuid}/reopen`

- Auth: Admin
- Permission: `admin.tickets.edit`
- Route name: `admin-tickets-reopen`
- Controller: [`TicketsController::reopen`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L459)

**Reopen ticket** Reopen a previously closed ticket by setting its status to the "open" status and clearing closed\_at.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

```bash
curl -X POST "$PANEL_URL/api/admin/tickets/$UUID/reopen" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:reopened`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-reopened), [`featherpanel:ticket:status:changed`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-changed)

Responses: `200` Ticket reopened successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket or status not found · `500` Internal server error

### GET `/api/admin/tickets/{uuid}`

- Auth: Admin
- Permission: `admin.tickets.view`
- Route name: `admin-tickets-show`
- Controller: [`TicketsController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L475)

**Get ticket by UUID** Retrieve a specific ticket by its UUID with all messages and attachments.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `ticket` | Ticket |  |
| `messages` | object\[\] | Ticket messages |
| `attachments` | object\[\] | Ticket attachments |

```bash
curl -X GET "$PANEL_URL/api/admin/tickets/$UUID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Ticket retrieved successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found

### PATCH `/api/admin/tickets/{uuid}`

- Auth: Admin
- Permission: `admin.tickets.edit`
- Route name: `admin-tickets-update`
- Controller: [`TicketsController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L490)

**Update ticket** Update an existing ticket (status, priority, category, etc.).

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

Request body: [`TicketUpdate`](https://featherpanel.com/docs/api/schemas/#schema-ticketupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `server_id` | integer | no | Server ID if ticket is related to a server |
| `category_id` | integer | no | Category ID |
| `priority_id` | integer | no | Priority ID |
| `status_id` | integer | no | Status ID |
| `title` | string | no | Ticket title |
| `description` | string | no | Ticket description |
| `closed_at` | string (date-time) | no | Ticket closed timestamp |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X PATCH "$PANEL_URL/api/admin/tickets/$UUID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"server_id":0,"category_id":0,"priority_id":0,"status_id":0,"title":"","description":"","closed_at":""}'
```

Plugin events: [`featherpanel:ticket:closed`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-closed), [`featherpanel:ticket:reopened`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-reopened), [`featherpanel:ticket:status:changed`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-status-changed), [`featherpanel:ticket:updated`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-updated)

Responses: `200` Ticket updated successfully · `400` Bad request - Validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found · `500` Internal server error

### DELETE `/api/admin/tickets/{uuid}`

- Auth: Admin
- Permission: `admin.tickets.delete`
- Route name: `admin-tickets-delete`
- Controller: [`TicketsController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/TicketsController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/tickets.php#L506)

**Delete ticket** Permanently delete a ticket. This will also delete all messages and attachments.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uuid` | path | string (uuid) | yes | Ticket UUID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/tickets/$UUID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:ticket:deleted`](https://featherpanel.com/docs/plugins/events/ticket/#ticket-deleted)

Responses: `200` Ticket deleted successfully · `400` Bad request - Invalid UUID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Ticket not found · `500` Internal server error
