Download attachment API
This article and the rest of the API documentation in this section are written for a technical audience — integrators and developers connecting external systems to Tickiti. Familiarity with HTTP, REST, JSON and bearer-token authentication is assumed.
The download endpoint returns the bytes of a single response attachment. Discover an attachment’s id from Show ticket or List responses, then fetch its content here. To keep the API uniformly JSON, the bytes are returned base64-encoded in the response body rather than as a binary download.
Endpoint
POST /api/v1/tickets/attachmentHeaders
Authorization: Bearer YOUR_TOKEN— required. Token must have thetickets:readability. Atickets:writetoken also works (write implies read).Content-Type: application/json— required. NoIdempotency-Keyis needed (this is a read).
Body
Required fields:
ticket_number— the ticket the attachment belongs to. Used to authorise the request (same queue-access check as the rest of the API) and to scope the lookup; the attachment must belong to this ticket.response_attachment_id— the attachment’sidfrom Show ticket / List responses.
Optional fields:
intent— set to"review_ok"to confirm download of an attachment type that is review-gated (see Error responses). Has no effect on always-allowed types.
Example
curl -X POST https://support.sole-provider.example/api/v1/tickets/attachment \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ticket_number": "220009",
"response_attachment_id": "14494"
}' | jq -r '.data.content_base64' | base64 -d > attachment.binSuccessful response
The attachment’s metadata and its bytes as content_base64. mime_type is detected from the bytes; file_size is the original byte count (the base64 string is about a third larger).
{
"ok": true,
"data": {
"id": "14494",
"response_id": "42",
"name": "UPDD Diag.zip",
"mime_type": "application/zip",
"sha256": "cc9b8a68...608baf",
"file_size": 1196962,
"is_inline": false,
"content_base64": "UEsDBBQAAAAIA..."
}
}Error responses
422 validation_failed—ticket_numberorresponse_attachment_idmissing.404 not_found— the ticket or attachment does not exist, the attachment does not belong to that ticket, or its stored file is missing.403 attachment_blocked— the attachment’s file type is hard-blocked by an administrator and cannot be downloaded.403 attachment_review_required— the file type is review-gated; resend with"intent": "review_ok"to confirm.413 attachment_too_large— the file exceeds the API download size limit (25 MB); use the web download instead.401 unauthenticated— bad or missing token.403 forbidden— token lacks thetickets:read(ortickets:write) ability, the user it acts as lacks access to the ticket’s queue, or the token owner is not a staff account.
What happens server-side
- Tickiti locates and queue-authorises the ticket, then loads the attachment and verifies it belongs to that ticket.
- For non-inline attachments it applies the administrator’s file-type rules (allowed / review / blocked), honouring
intentfor review-gated types. - It reads the stored file (attachments are content-addressed by SHA-256) and returns it base64-encoded, with a detected MIME type.