Attachments¶
Attachments are files associated with tickets. You can upload documents, images, and other files to provide additional context for support requests.
Endpoints¶
| Method | Endpoint | Description | Scope Required |
|---|---|---|---|
| GET | /v1/tickets/{ticket_id}/attachments |
List attachments | attachments:read |
| GET | /v1/tickets/{ticket_id}/attachments/{id} |
Get attachment | attachments:read |
| GET | /v1/tickets/{ticket_id}/attachments/{id}/download |
Get download URL | attachments:read |
| POST | /v1/tickets/{ticket_id}/attachments |
Upload attachment | attachments:write |
| DELETE | /v1/tickets/{ticket_id}/attachments/{id} |
Delete attachment | attachments:delete |
The Attachment Object¶
{
"id": "456e7890-e12b-34c5-d678-901234567890",
"ticket_id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "screenshot.png",
"content_type": "image/png",
"size_bytes": 245780,
"uploaded_by_user_id": "789e0123-f45b-67c8-d901-234567890abc",
"created_at": "2025-01-16T12:00:00Z"
}
Attributes¶
| Field | Type | Description |
|---|---|---|
id |
UUID | Unique attachment identifier |
ticket_id |
UUID | ID of the parent ticket |
filename |
string | Original filename |
content_type |
string | MIME type of the file |
size_bytes |
integer | File size in bytes |
uploaded_by_user_id |
UUID | ID of user who uploaded |
created_at |
datetime | Upload timestamp |
File Restrictions¶
Maximum File Size¶
30 MB per file.
Allowed File Types¶
| Category | MIME Types |
|---|---|
| Documents | text/plain, text/html, application/pdf |
| Images | image/png, image/jpeg, image/gif, image/webp |
| Videos | video/mp4, video/webm, video/ogg, video/quicktime |
| Archives | application/zip, application/x-7z-compressed, application/gzip |
List Attachments¶
Retrieve all attachments for a ticket.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
ticket_id |
UUID | The ticket ID |
Examples¶
Response¶
[
{
"id": "456e7890-e12b-34c5-d678-901234567890",
"ticket_id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "screenshot.png",
"content_type": "image/png",
"size_bytes": 245780,
"created_at": "2025-01-16T12:00:00Z"
}
]
Get Attachment¶
Retrieve attachment metadata (not the file content).
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
ticket_id |
UUID | The ticket ID |
attachment_id |
UUID | The attachment ID |
Examples¶
Response¶
{
"id": "456e7890-e12b-34c5-d678-901234567890",
"ticket_id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "screenshot.png",
"content_type": "image/png",
"size_bytes": 245780,
"uploaded_by_user_id": "789e0123-f45b-67c8-d901-234567890abc",
"created_at": "2025-01-16T12:00:00Z"
}
Get Download URL¶
Get a signed URL to download the attachment. The URL is valid for 1 hour.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
ticket_id |
UUID | The ticket ID |
attachment_id |
UUID | The attachment ID |
Examples¶
# Get the signed URL
curl -X GET "https://api.toptickets.app/v1/tickets/550e8400-e29b-41d4-a716-446655440000/attachments/456e7890-e12b-34c5-d678-901234567890/download" \
-H "Authorization: Bearer YOUR_API_KEY"
# Then download using the signed URL (no auth needed)
curl -o screenshot.png "SIGNED_URL_FROM_RESPONSE"
import requests
TICKET_ID = "550e8400-e29b-41d4-a716-446655440000"
ATTACHMENT_ID = "456e7890-e12b-34c5-d678-901234567890"
# Get the signed URL
response = requests.get(
f"https://api.toptickets.app/v1/tickets/{TICKET_ID}/attachments/{ATTACHMENT_ID}/download",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
signed_url = response.json()["signed_url"]
# Download the file (no auth header needed)
file_response = requests.get(signed_url)
with open("screenshot.png", "wb") as f:
f.write(file_response.content)
Response¶
{
"signed_url": "https://storage.supabase.co/object/sign/attachments/...",
"expires_at": "2025-01-16T13:00:00Z"
}
URL Expiration
Signed URLs expire after 1 hour. Generate a new URL if the previous one expired.
Upload Attachment¶
Upload a file to a ticket.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
ticket_id |
UUID | The ticket ID |
Request¶
Send the file as multipart/form-data:
Examples¶
import requests
TICKET_ID = "550e8400-e29b-41d4-a716-446655440000"
with open("/path/to/screenshot.png", "rb") as f:
response = requests.post(
f"https://api.toptickets.app/v1/tickets/{TICKET_ID}/attachments",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"file": ("screenshot.png", f, "image/png")}
)
print(response.json())
Response (201 Created)¶
{
"id": "567f8901-f23c-45d6-e789-012345678901",
"ticket_id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "screenshot.png",
"content_type": "image/png",
"size_bytes": 245780,
"uploaded_by_user_id": "789e0123-f45b-67c8-d901-234567890abc",
"created_at": "2025-01-16T14:30:00Z"
}
Error Responses¶
File too large (400 Bad Request):
Invalid file type (400 Bad Request):
Delete Attachment¶
Delete an attachment.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
ticket_id |
UUID | The ticket ID |
attachment_id |
UUID | The attachment ID |
Examples¶
import requests
TICKET_ID = "550e8400-e29b-41d4-a716-446655440000"
ATTACHMENT_ID = "456e7890-e12b-34c5-d678-901234567890"
response = requests.delete(
f"https://api.toptickets.app/v1/tickets/{TICKET_ID}/attachments/{ATTACHMENT_ID}",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
if response.status_code == 204:
print("Attachment deleted")
Response¶
Returns 204 No Content on success.