---
title: "Attach a file to a ticket"
method: POST
path: "/api/tickets/{id}/attachments"
tags: ["support"]
---

# Attach a file to a ticket

`POST /api/tickets/{id}/attachments`

## Request

- Base URL: `https://api.depixapp.com`
- URL: `https://api.depixapp.com/api/tickets/{id}/attachments`
- Auth: none required

Uploads ONE file (base64 in file_b64, max ~3 MB) and forwards it to the support team — use it to send a screenshot or an app diagnostics/log file when reporting a bug. Same principal + state machine as a reply: an answered ticket returns to awaiting_reply; an auto-closed ticket within 7 days reopens. The file is forwarded to support, NOT stored or served back — the response records only its name/type. Returns 503 attachment_unavailable when the ticket has no support channel yet (retry shortly, or continue with a text reply). NO scope required.

## Path parameters

- `id` string, required

## Request body

- TicketAttachmentRequest: Attach ONE file to a ticket. The bytes go in file_b64 (base64, no data: URI prefix) and are forwarded to the support team's Telegram topic — not stored or served back. Max ~3 MB decoded. Same state machine as a reply: an answered ticket returns to awaiting_reply; an auto-closed ticket within 7 days reopens.
  - `filename` string, required: Filename shown to support (sanitized; max 200 chars).
  - `content_type` 'image/png' | 'image/jpeg' | 'image/webp' | 'application/pdf' | 'text/plain' | 'application/json', required: File MIME type.
  - `file_b64` string, required: The file bytes, base64-encoded (no data: URI prefix). Max ~3 MB decoded.
  - `caption` string: Optional note shown with the file (max 400 chars).

## Response `201`

Attachment forwarded to support and recorded on the thread.

- TicketMessageResponse: The posted message plus the updated ticket.
  - `message` TicketMessage, required: A single message in a ticket thread.
    - `id` string, required: Message id.
    - `sender` 'user' | 'admin' | 'system', required: Who sent the message.
    - `body` string, required: Message body.
    - `created_at` string, required: Message timestamp (RFC 3339 UTC).
    - `attachment` TicketAttachment: Metadata of a file attached to a message. The bytes are forwarded to the support team (not stored or served back) — only the name and type are exposed.
      - `name` string, required: Original filename (sanitized).
      - `mime` string, nullable, required: Content type (image/png, image/jpeg, image/webp, application/pdf, text/plain or application/json).
  - `ticket` Ticket, required: A support ticket (summary view).
    - `id` string, required: Ticket id (tkt_*).
    - `opener_type` 'human' | 'agent', required: Who opened the ticket, snapshotted from the account type at creation.
    - `status` union, required: Ticket lifecycle status — the enum below is the complete, closed set. `closed` is terminal (an auto-closed ticket may be reopened by replying within 7 days). Terminal states (safe to stop polling): closed.
      - 'awaiting_reply': The ball is with support — a reply from support is pending. NEVER auto-closes.
      - 'answered': Support replied; awaiting the user. Auto-closes after 2 business days of no user reply.
      - 'closed': TERMINAL — closed by the user, support, or the 2-business-day auto-close sweep.
    - `subject` string, required: Ticket subject (4–120 chars).
    - `category` 'bug' | 'question' | 'account' | 'payment' | 'other', required: Ticket category.
    - `created_at` string, required: Creation timestamp (RFC 3339 UTC).
    - `last_activity_at` string, required: Timestamp of the last user/admin message (RFC 3339 UTC). System messages do not bump it.
    - `closed_reason` string, nullable, required: Why the ticket closed: 'user', 'admin' or 'auto' — null while open.
    - `closed_at` string, nullable, required: Close timestamp (RFC 3339 UTC) — null while open. Anchors the 7-day reopen window for auto-closed tickets.
    - `rating` integer, nullable, required: Satisfaction score the ticket owner gave (0 = worst, 10 = best) — null until rated. Only a closed ticket can be rated, and only once.
    - `rated_at` string, nullable, required: When the rating was submitted (RFC 3339 UTC) — null until rated.

## Other responses

- `400`: Validation failure — missing/invalid content_type or file_b64.
- `401`: Missing/invalid credentials. `invalid_api_key` for a failed sk_* lookup (revoked/expired/unknown); `invalid_token` for a bad or missing JWT/Authorization header.
- `404`: Ticket not found — includes rows owned by another account (ownership is never disclosed).
- `409`: The ticket is closed (user/admin close, or an auto-close past its 7-day reopen window). Open a new ticket.
- `413`: The attachment exceeds the maximum size (~3 MB).
- `429`: Rate limited (per-IP, per-key or per-merchant window). Retry after `retry_after` seconds (also in the Retry-After header).
- `503`: Attachments are temporarily unavailable for this ticket (no support channel yet, or the forward failed). Retry shortly or continue with a text reply.

---

[API](https://skmtc.dev/depixapp/apis/depix-api.md) · [All operations](https://skmtc.dev/depixapp/apis/depix-api/llms.txt) · [OpenAPI document](https://skmtc.dev/depixapp/apis/depix-api/revisions/04094536dd0f?raw)
