---
title: "List a ticket's thread"
method: GET
path: "/tickets/{id}/messages"
tags: ["tickets"]
---

# List a ticket's thread

`GET /tickets/{id}/messages`

## Request

- Base URL: `https://api.instruxi.dev/api/v1/enforcer`
- URL: `https://api.instruxi.dev/api/v1/enforcer/tickets/{id}/messages`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `X-API-Key`

Oldest first by default (sort_dir=desc for newest first). Internal staff notes are visible to staff only. from/to bound created_at (since/until are accepted aliases, so an incremental poll sends since=<last created_at>): YYYY-MM-DD is an inclusive whole UTC day, RFC3339 an exact instant (from inclusive, to exclusive); malformed is 400 invalid_from / invalid_to. total counts the messages matching the window.

## Path parameters

- `id` string, required

## Query parameters

- `from` string
- `to` string
- `since` string
- `sort` 'created'
- `sort_dir` 'asc' | 'desc'
- `limit` integer
- `offset` integer

## Response `200`

OK

- InternalDeliveryHttpHandlerTicketMessagePageResponse
  - `data` EnforcerV3InternalDomainTicketMessage[]
    - `author_account_id` string
    - `body` string
    - `created_at` string
    - `file_ids` string[]: FileIDs are enforcer-files ids. Persisted now; the presigned-URL broker that makes them readable cross-user is Phase 2 (docs/plans/ticket-api.md).
    - `id` string
    - `internal` boolean: Internal marks a staff-only note: never shown to the requester, never notifies. The usecase fences both writing and reading it to staff.
    - `ticket_id` string
  - `limit` integer
  - `offset` integer
  - `success` boolean
  - `total` integer

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found

---

[API](https://skmtc.dev/instruxi/apis/enforcer-api.md) · [All operations](https://skmtc.dev/instruxi/apis/enforcer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/instruxi/apis/enforcer-api/revisions/fa82bc1becc0?raw)
