---
title: "Reply on a ticket"
method: POST
path: "/tickets/{id}/messages"
tags: ["tickets"]
---

# Reply on a ticket

`POST /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`

Append a message. internal=true is staff-only. Public replies drive the lifecycle: a requester reply reopens, a staff reply marks the ticket pending, and each notifies the other side.

## Path parameters

- `id` string, required

## Request body

- InternalDeliveryHttpHandlerTicketMessageRequest
  - `body` string
  - `file_ids` string[]
  - `internal` boolean

## Response `200`

OK

- InternalDeliveryHttpHandlerTicketMessageResponse
  - `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
  - `success` boolean

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict

---

[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)
