Attachments
Attach files to tickets or messages to provide visual context, share logs, or send supporting materials directly within a support conversation. Attachments are stored securely and served via signed CDN URLs that expire after one hour.
Supported file types: JPEG, PNG, GIF, WebP, MP4, MOV, PDF, ZIP. Maximum file size: 20 MB per upload.
Upload Attachment
/v1/attachments🔒 Auth requiredUpload a file using multipart/form-data. Returns attachment metadata and a signed CDN URL valid for one hour. Associate the returned id with a ticket message to surface the file in the support thread.
| Parameter | Type | Required | Description |
|---|---|---|---|
| ticketId | string | Required | The ID of the ticket this attachment belongs to. Must be an existing ticket in your organisation. |
| file | binary | Required | Raw file binary. Must be sent as a multipart/form-data field. Maximum 20 MB. Accepted types: JPEG, PNG, GIF, WebP, MP4, MOV, PDF, ZIP. |
| fileName | string | Optional | Human-readable file name to store alongside the attachment. Defaults to the original filename from the multipart upload if omitted. |
| mimeType | string | Optional | MIME type of the file (e.g. image/jpeg, application/pdf). If omitted, Keme will attempt to detect the type automatically from the file content. |
1curl -X POST https://api.kemegames.com/v1/attachments \2 -H "Authorization: Bearer sk_live_••••••••••••••••" \3 --form ticketId="tkt_01hx9z3v7k2r4m8n6p0q" \4 --form fileName="screenshot.jpg" \5 --form mimeType="image/jpeg" \6 --form file=@"/path/to/screenshot.jpg"
1{2 "id": "att_01hx9z4b2c3d5e6f7g8h",3 "ticketId": "tkt_01hx9z3v7k2r4m8n6p0q",4 "fileName": "screenshot.jpg",5 "mimeType": "image/jpeg",6 "sizeBytes": 245678,7 "url": "https://cdn.kemegames.com/att/01hx9z4b2c3d5e6f7g8h/screenshot.jpg?sig=eyJhbGciOiJIUzI1NiJ9",8 "urlExpiresAt": "2026-06-16T10: 00: 00Z",9 "uploadedBy": {10 "id": "usr_01hx9abc",11 "email": "agent@studio.com"12 },13 "createdAt": "2026-06-15T09: 00: 00Z"14}
Get Attachment Metadata
/v1/attachments/:id🔒 Auth requiredRetrieve metadata for a specific attachment by its ID. The response includes a refreshed signed CDN URL valid for one hour from the time of the request.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | The unique attachment ID returned when the file was uploaded (e.g. att_01hx9z4b2c3d5e6f7g8h). |
1curl https://api.kemegames.com/v1/attachments/att_01hx9z4b2c3d5e6f7g8h \2 -H "Authorization: Bearer sk_live_••••••••••••••••"
1{2 "id": "att_01hx9z4b2c3d5e6f7g8h",3 "ticketId": "tkt_01hx9z3v7k2r4m8n6p0q",4 "fileName": "screenshot.jpg",5 "mimeType": "image/jpeg",6 "sizeBytes": 245678,7 "url": "https://cdn.kemegames.com/att/01hx9z4b2c3d5e6f7g8h/screenshot.jpg?sig=eyJhbGciOiJIUzI1NiJ9",8 "urlExpiresAt": "2026-06-16T10: 00: 00Z",9 "uploadedBy": {10 "id": "usr_01hx9abc",11 "email": "agent@studio.com"12 },13 "createdAt": "2026-06-15T09: 00: 00Z"14}
Get Signed Download URL
Use this endpoint to obtain a fresh signed CDN URL for downloading an attachment. This is useful when an existing URL returned by a prior metadata fetch has expired or is about to expire.
/v1/attachments/:id/download🔒 Auth requiredReturns a freshly signed CDN download URL for the specified attachment. The URL is valid for one hour from the time of the response.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | The unique attachment ID (e.g. att_01hx9z4b2c3d5e6f7g8h). |
1curl https://api.kemegames.com/v1/attachments/att_01hx9z4b2c3d5e6f7g8h/download \2 -H "Authorization: Bearer sk_live_••••••••••••••••"
1{2 "url": "https://cdn.kemegames.com/att/01hx9z4b2c3d5e6f7g8h/screenshot.jpg?sig=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",3 "expiresAt": "2026-06-16T10: 00: 00Z"4}
GET /v1/attachments/:id/download to obtain a refreshed URL. Do not store raw CDN URLs in your database as permanent references — always re-fetch on demand.Delete Attachment
Permanently removes an attachment and its underlying file from storage. This action cannot be undone. The attachment will no longer be retrievable and any existing signed URLs will become invalid immediately.
/v1/attachments/:id🔒 Auth requiredPermanently deletes the specified attachment and invalidates all existing signed CDN URLs for it. Returns 204 No Content on success.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | Required | The unique attachment ID to delete (e.g. att_01hx9z4b2c3d5e6f7g8h). |
1curl -X DELETE https://api.kemegames.com/v1/attachments/att_01hx9z4b2c3d5e6f7g8h \2 -H "Authorization: Bearer sk_live_••••••••••••••••"
Error Codes
The Attachments API returns standard Keme error envelopes. Common error codes specific to this resource:
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | attachment.unsupported_type | The uploaded file type is not supported. Accepted: JPEG, PNG, GIF, WebP, MP4, MOV, PDF, ZIP. |
| 400 | attachment.file_too_large | The file exceeds the 20 MB maximum size limit. |
| 400 | attachment.ticket_not_found | The provided ticketId does not exist or does not belong to your organisation. |
| 401 | auth.token_invalid | The Bearer token is missing, malformed, or expired. |
| 403 | attachment.access_denied | Your API key does not have permission to access this attachment. |
| 404 | attachment.not_found | No attachment exists with the given ID. |
| 413 | attachment.payload_too_large | The request payload exceeds server limits. Ensure the file is within 20 MB. |
| 429 | rate_limit.exceeded | Too many requests. Back off and retry after the duration specified in the Retry-After header. |
Rate Limits
Upload requests are rate-limited to 60 requests per minute per API key. Read and delete requests share the standard API limit of 300 requests per minute. When a limit is exceeded, the API returns 429 Too Many Requests with a Retry-After header indicating the number of seconds to wait before retrying.