Files
Esta página aún no está disponible en tu idioma.
Files represent attachments uploaded to tickets. Each file object includes metadata (name, MIME type, size) and a short-lived signed URL you can use to download the file directly.
Signed URLs expire after 300 seconds. Fetch a fresh URL by calling Retrieve a file again before it expires.
The file object
Section titled “The file object”{ "object": "file", "id": 142, "ticket_id": "T-1042", "filename": "a3f9c1b2.jpg", "original_name": "cracked-screen-photo.jpg", "mime_type": "image/jpeg", "size_bytes": 284310, "uploaded_by": "tech@example.com", "portal_visible": true, "download_url": "/api/attachments/T-1042/a3f9c1b2.jpg?sig=...", "download_url_ttl_sec": 300, "created_at": "2025-11-10T14:22:00.000Z"}| Field | Type | Description |
|---|---|---|
id | integer | File ID |
ticket_id | string | Ticket the file belongs to |
filename | string | Stored filename (opaque; use original_name for display) |
original_name | string | null | Original filename as uploaded |
mime_type | string | null | MIME type (e.g. image/jpeg, application/pdf) |
size_bytes | integer | null | File size in bytes |
uploaded_by | string | null | Email or identifier of the uploader |
portal_visible | boolean | Whether the file is visible in the customer portal |
download_url | string | null | Signed URL valid for download_url_ttl_sec seconds |
download_url_ttl_sec | integer | null | Signed URL lifetime in seconds (300) |
created_at | string | ISO-8601 upload timestamp |
List files
Section titled “List files”GET /api/v1/filesReturns attachment metadata sorted by newest first. Use ticket_id to scope results to a single ticket, without it the endpoint returns all attachments across all tickets.
Scope required: files.read
Query parameters
Section titled “Query parameters”| Parameter | Type | Description |
|---|---|---|
ticket_id | string | Filter to a specific ticket (strongly recommended) |
limit | integer | Page size, 1–100 (default: 25) |
cursor | string | Opaque cursor from a previous response’s next_cursor |
curl "https://app.benchkey.com/api/v1/files?ticket_id=T-1042&limit=20" \ -H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"Node.js
Section titled “Node.js”const res = await fetch( "https://app.benchkey.com/api/v1/files?ticket_id=T-1042&limit=20", { headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } });const { data, has_more, next_cursor } = await res.json();Response
Section titled “Response”{ "object": "list", "data": [ { "object": "file", "id": 142, "ticket_id": "T-1042", "filename": "a3f9c1b2.jpg", "original_name": "cracked-screen-photo.jpg", "mime_type": "image/jpeg", "size_bytes": 284310, "uploaded_by": "tech@example.com", "portal_visible": true, "download_url": "/api/attachments/T-1042/a3f9c1b2.jpg?sig=...", "download_url_ttl_sec": 300, "created_at": "2025-11-10T14:22:00.000Z" } ], "has_more": false, "next_cursor": null}Hidden and soft-deleted tickets are excluded from all results. See Pagination for how to page through results.
Retrieve a file
Section titled “Retrieve a file”GET /api/v1/files/:idReturns a single file object with a fresh signed download URL.
Scope required: files.read
curl "https://app.benchkey.com/api/v1/files/142" \ -H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"Node.js
Section titled “Node.js”const res = await fetch( "https://app.benchkey.com/api/v1/files/142", { headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" } });const file = await res.json();// file.download_url is valid for 300 secondsResponse
Section titled “Response”Returns the file object. Returns 404 if the file does not exist or its ticket is hidden or deleted.
Downloading a file
Section titled “Downloading a file”The download_url in every file object is a relative signed URL that resolves against https://app.benchkey.com. Append it to the base URL and make an unauthenticated GET request, no API key is needed once you have the signed URL.
curl "https://app.benchkey.com/api/attachments/T-1042/a3f9c1b2.jpg?sig=..." \ -o cracked-screen-photo.jpgconst fileObj = await fetch("https://app.benchkey.com/api/v1/files/142", { headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" },}).then(r => r.json());
// Download using the signed URL (no API key needed)const blob = await fetch(`https://app.benchkey.com${fileObj.download_url}`).then(r => r.blob());Signed URLs expire after 300 seconds. If your workflow takes longer, retrieve the file object again to get a fresh URL.
Error codes
Section titled “Error codes”| HTTP status | Code | Meaning |
|---|---|---|
400 | invalid_id | :id is not a valid positive integer, or is not a safe integer |
400 | invalid_query | ticket_id query parameter is malformed |
400 | invalid_cursor | cursor is malformed |
404 | not_found | File not found, or its ticket is hidden or deleted |
403 | insufficient_scope | API key lacks files.read |
See Errors for the full error envelope format.