# Files

## List Files & Folders in Computer

> Lists the file system content of a running machine.\
> \
> This endpoint allows you to browse the machine's file system remotely. It returns files and folders in the specified path.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Machine ID |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`path\` | String | Yes | Folder path to list. Must be Windows format with escaped backslashes (e.g., "C:\\\Users", "C:\\\Users\\\Documents") |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (machine is not running) |\
> \| 404 | Machine not found or does not belong to organization |\
> \| 4710 | Permission required |\
> \
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`content\` | Array | Array of file system content objects |\
> \| \`content\[].path\` | String | Full path of the file or folder |\
> \| \`content\[].name\` | String | File or folder name |\
> \| \`content\[].is\_directory\` | Boolean | true if directory, false if file |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "path": "C:\\\Users"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "content": \[\
> &#x20;       {\
> &#x20;           "path": "C:\\\Users\\\Administrator",\
> &#x20;           "name": "Administrator",\
> &#x20;           "is\_directory": true\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "path": "C:\\\Users\\\Public",\
> &#x20;           "name": "Public",\
> &#x20;           "is\_directory": true\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T11:55:10Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/list-content":{"post":{"summary":"List Files & Folders in Computer","responses":{"200":{"description":"File system content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListContentResponse"}}}},"400":{"description":"Bad request (machine is not running)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists the file system content of a running machine.\n\nThis endpoint allows you to browse the machine's file system remotely. It returns files and folders in the specified path.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Machine ID |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `path` | String | Yes | Folder path to list. Must be Windows format with escaped backslashes (e.g., \"C:\\\\Users\", \"C:\\\\Users\\\\Documents\") |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (machine is not running) |\n| 404 | Machine not found or does not belong to organization |\n| 4710 | Permission required |\n\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `content` | Array | Array of file system content objects |\n| `content[].path` | String | Full path of the file or folder |\n| `content[].name` | String | File or folder name |\n| `content[].is_directory` | Boolean | true if directory, false if file |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Request Body Example**\n\n``` json\n{\n  \"path\": \"C:\\\\Users\"\n}\n\n ```\n\n### **Response Example**\n\n``` json\n{\n    \"content\": [\n        {\n            \"path\": \"C:\\\\Users\\\\Administrator\",\n            \"name\": \"Administrator\",\n            \"is_directory\": true\n        },\n        {\n            \"path\": \"C:\\\\Users\\\\Public\",\n            \"name\": \"Public\",\n            \"is_directory\": true\n        }\n    ],\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T11:55:10Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string"}}}}}}}}},"components":{"schemas":{"ListContentResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"content":{"type":"array","description":"List of files and directories at the specified path","items":{"$ref":"#/components/schemas/FileSystemItem"}}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileSystemItem":{"type":"object","description":"File or directory item from machine file system","properties":{"path":{"type":"string","description":"Full path to the file or directory"},"name":{"type":"string","description":"Name of the file or directory"},"is_directory":{"type":"boolean","description":"True if this item is a directory, false if it's a file"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Shared Files & Folders in Vagon Files

> Lists the files and folders in Organization Shared Folder.\
> \
> This endpoint lists files stored in the organization's shared storage. These files are accessible to all organization members.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Query Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`parent\_id\` | Integer | Parent folder ID. 0 = root folder (organization's shared root folder) |\
> \| \`page\` | Integer | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | Records per page. Default: 20 |\
> \| \`q\` | String | Search query. Searches by file/directory name |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Parent folder not found |\
> \| 4710 | Permission required |\
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`files\` | Array | Array of file/folder objects |\
> \| \`files\[].id\` | String | File/folder ID |\
> \| \`files\[].type\` | String | Always "file" |\
> \| \`files\[].attributes.name\` | String | File or folder name |\
> \| \`files\[].attributes.size\` | Integer | File size in bytes. 0 for directories |\
> \| \`files\[].attributes.content\_type\` | String | MIME type (e.g., "image/png") or "directory" |\
> \| \`files\[].attributes.region\` | String | AWS region where file is stored |\
> \| \`files\[].attributes.status\` | String | File status (e.g., "upload\_completed") |\
> \| \`files\[].attributes.object\_type\` | String | Type: "file", "directory", or "root" |\
> \| \`files\[].attributes.path\` | String | Full path of the file/folder. null for some files |\
> \| \`files\[].attributes.parent\_id\` | Integer | Parent folder ID |\
> \| \`files\[].attributes.last\_modified\_date\` | String | ISO 8601 timestamp of last modification |\
> \| \`files\[].attributes.file\_storage\_size\` | Integer | Total file storage size (in bytes). null for non-root |\
> \| \`files\[].attributes.file\_storage\_usage\` | Integer | Used file storage (in bytes). null for non-root |\
> \| \`files\[].attributes.user\` | Object | User who owns the file (null if none) |\
> \| \`files\[].attributes.user.id\` | String | User UUID |\
> \| \`files\[].attributes.user.type\` | String | Always "user" |\
> \| \`files\[].attributes.user.attributes.email\` | String | User email |\
> \| \`files\[].attributes.user.attributes.name\` | String | User name |\
> \| \`files\[].attributes.machine\_id\` | Integer | Machine ID the file belongs to (null for organization shared storage) |\
> \| \`current\` | Object | Current directory object (same structure as file objects). null if at root |\
> \| \`count\` | Integer | Total number of files/folders in current directory |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "18093",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "example.zip",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/example.zip",\
> &#x20;               "parent\_id": 5122,\
> &#x20;               "last\_modified\_date": null,\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "18088",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Project Folder",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/Project Folder",\
> &#x20;               "parent\_id": 5122,\
> &#x20;               "last\_modified\_date": null,\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "5122",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Teams Shared Folder",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "root",\
> &#x20;           "path": null,\
> &#x20;           "parent\_id": null,\
> &#x20;           "last\_modified\_date": "2026-02-04T12:07:59.204Z",\
> &#x20;           "file\_storage\_size": 26843545600,\
> &#x20;           "file\_storage\_usage": 0,\
> &#x20;           "user": null,\
> &#x20;           "machine\_id": null\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:17:46Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files":{"get":{"summary":"List Shared Files & Folders in Vagon Files","parameters":[{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Parent folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists the files and folders in Organization Shared Folder.\n\nThis endpoint lists files stored in the organization's shared storage. These files are accessible to all organization members.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `parent_id` | Integer | Parent folder ID. 0 = root folder (organization's shared root folder) |\n| `page` | Integer | Page number. Default: 1 |\n| `per_page` | Integer | Records per page. Default: 20 |\n| `q` | String | Search query. Searches by file/directory name |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Parent folder not found |\n| 4710 | Permission required |\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `files` | Array | Array of file/folder objects |\n| `files[].id` | String | File/folder ID |\n| `files[].type` | String | Always \"file\" |\n| `files[].attributes.name` | String | File or folder name |\n| `files[].attributes.size` | Integer | File size in bytes. 0 for directories |\n| `files[].attributes.content_type` | String | MIME type (e.g., \"image/png\") or \"directory\" |\n| `files[].attributes.region` | String | AWS region where file is stored |\n| `files[].attributes.status` | String | File status (e.g., \"upload_completed\") |\n| `files[].attributes.object_type` | String | Type: \"file\", \"directory\", or \"root\" |\n| `files[].attributes.path` | String | Full path of the file/folder. null for some files |\n| `files[].attributes.parent_id` | Integer | Parent folder ID |\n| `files[].attributes.last_modified_date` | String | ISO 8601 timestamp of last modification |\n| `files[].attributes.file_storage_size` | Integer | Total file storage size (in bytes). null for non-root |\n| `files[].attributes.file_storage_usage` | Integer | Used file storage (in bytes). null for non-root |\n| `files[].attributes.user` | Object | User who owns the file (null if none) |\n| `files[].attributes.user.id` | String | User UUID |\n| `files[].attributes.user.type` | String | Always \"user\" |\n| `files[].attributes.user.attributes.email` | String | User email |\n| `files[].attributes.user.attributes.name` | String | User name |\n| `files[].attributes.machine_id` | Integer | Machine ID the file belongs to (null for organization shared storage) |\n| `current` | Object | Current directory object (same structure as file objects). null if at root |\n| `count` | Integer | Total number of files/folders in current directory |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Response Example\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"18093\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"example.zip\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/example.zip\",\n                \"parent_id\": 5122,\n                \"last_modified_date\": null,\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        },\n        {\n            \"id\": \"18088\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"Project Folder\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/Project Folder\",\n                \"parent_id\": 5122,\n                \"last_modified_date\": null,\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"5122\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Teams Shared Folder\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"root\",\n            \"path\": null,\n            \"parent_id\": null,\n            \"last_modified_date\": \"2026-02-04T12:07:59.204Z\",\n            \"file_storage_size\": 26843545600,\n            \"file_storage_usage\": 0,\n            \"user\": null,\n            \"machine_id\": null\n        }\n    },\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:17:46Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Upload File & Create Directory

> Creates a new file or directory and initiates multipart upload for files.\
> \
> This endpoint creates a file or directory entry. For files, it also generates presigned S3 URLs for multipart upload.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`machine\_id\` | Integer | No | Machine ID. If provided, file/folder is created in machine's storage. null = organization shared storage |\
> \| \`file\_name\` | String | Yes | File or directory name. Must be unique within the parent folder (unless overwrite=true) |\
> \| \`object\_type\` | String | Yes | Type: \`"file"\` or \`"directory"\` |\
> \| \`content\_type\` | String | Yes (files only) | MIME type for files (e.g., "application/pdf", "image/png", "text/plain"). Required when \`object\_type\` is \`"file"\` |\
> \| \`size\` | Integer | Yes (files only) | File size in bytes. Required when \`object\_type\` is \`"file"\` |\
> \| \`chunk\_size\` | Integer | No | Chunk size in MB for multipart upload. Default: 250 MB. Only used for files |\
> \| \`overwrite\` | Boolean | No | If true, overwrites existing file with same name. Default: false |\
> \| \`parent\_id\` | Integer | Yes | Parent folder ID. Use \`0\` for root folder (machine root if machine\_id provided, organization root if machine\_id is null) |\
> \
> \#### \*\*Chunk Size Explanation\*\*\
> \
> \- Files larger than chunk\_size are uploaded in multiple parts\
> &#x20;   \
> \- Default chunk size is 250 MB\
> &#x20;   \
> \- Smaller chunks: More reliable on slow/unstable networks, easier to retry failed parts\
> &#x20;   \
> \- Larger chunks: Fewer requests, faster upload for stable networks\
> &#x20;   \
> \- Each part is uploaded separately to S3, then combined\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid object\_type, missing required fields, parent folder not found or deleted) |\
> \| 404 | Machine not found |\
> \| 450 | Storage full |\
> \| 451 | File already exists (when overwrite=false) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Success Response Fields (File)\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | File ID (use this in complete endpoint) |\
> \| \`uid\` | String | Unique identifier for the file |\
> \| \`upload\_urls\` | Array | Array of presigned S3 URLs for multipart upload. Each URL is for one chunk |\
> \| \`upload\_urls\[].part\_number\` | Integer | Part number (starts from 1) |\
> \| \`upload\_urls\[].url\` | String | Presigned S3 URL for uploading this part |\
> \| \`chunk\_size\` | Integer | Chunk size in MB used for upload |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Fields (Directory)\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | Integer | Directory ID |\
> \| \`uid\` | String | Unique identifier for the directory |\
> \| \`upload\_urls\` | null | Always null for directories |\
> \| \`chunk\_size\` | Integer | Chunk size (not used for directories) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "file\_name": "example.zip",\
> &#x20; "object\_type": "file",\
> &#x20; "content\_type": "application/zip",\
> &#x20; "size": 104857600,\
> &#x20; "chunk\_size": 250,\
> &#x20; "overwrite": false,\
> &#x20; "parent\_id": 1\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example (File)\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "id": 6731,\
> &#x20; "uid": "string",\
> &#x20; "upload\_urls": \[\
> &#x20;   {\
> &#x20;     "part\_number": 1,\
> &#x20;     "url": "<https://s3.amazonaws.com/bucket/file?uploadId=xyz\\&partNumber=1\\&X-Amz-Signature=..."\\>
> &#x20;   },\
> &#x20;   {\
> &#x20;     "part\_number": 2,\
> &#x20;     "url": "<https://s3.amazonaws.com/bucket/file?uploadId=xyz\\&partNumber=2\\&X-Amz-Signature=..."\\>
> &#x20;   }\
> &#x20; ],\
> &#x20; "chunk\_size": 250,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Example (Directory)\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "id": 124,\
> &#x20; "uid": "def456-ghi789-jkl012",\
> &#x20; "upload\_urls": null,\
> &#x20; "chunk\_size": 250,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Upload Flow for Files\*\*\
> \
> 1\. Call this endpoint to create file entry and get upload URLs\
> &#x20;   \
> 2\. For each part in \`upload\_urls\`:\
> &#x20;   \
> &#x20;   \- Make PUT request to the URL with the file chunk data\
> &#x20;       \
> &#x20;   \- Save the \`ETag\` header from the PUT response\
> &#x20;       \
> 3\. Call \`POST /files/:id/complete\` with all part numbers and ETags to finalize upload\
> &#x20;   \
> 4\. Directory creation is immediate (no upload needed)

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files":{"post":{"summary":"Upload File & Create Directory","responses":{"200":{"description":"File or directory created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFileResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"450":{"description":"Storage full","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error450Response"}}}},"451":{"description":"File already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error451Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Creates a new file or directory and initiates multipart upload for files.\n\nThis endpoint creates a file or directory entry. For files, it also generates presigned S3 URLs for multipart upload.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `machine_id` | Integer | No | Machine ID. If provided, file/folder is created in machine's storage. null = organization shared storage |\n| `file_name` | String | Yes | File or directory name. Must be unique within the parent folder (unless overwrite=true) |\n| `object_type` | String | Yes | Type: `\"file\"` or `\"directory\"` |\n| `content_type` | String | Yes (files only) | MIME type for files (e.g., \"application/pdf\", \"image/png\", \"text/plain\"). Required when `object_type` is `\"file\"` |\n| `size` | Integer | Yes (files only) | File size in bytes. Required when `object_type` is `\"file\"` |\n| `chunk_size` | Integer | No | Chunk size in MB for multipart upload. Default: 250 MB. Only used for files |\n| `overwrite` | Boolean | No | If true, overwrites existing file with same name. Default: false |\n| `parent_id` | Integer | Yes | Parent folder ID. Use `0` for root folder (machine root if machine_id provided, organization root if machine_id is null) |\n\n#### **Chunk Size Explanation**\n\n- Files larger than chunk_size are uploaded in multiple parts\n    \n- Default chunk size is 250 MB\n    \n- Smaller chunks: More reliable on slow/unstable networks, easier to retry failed parts\n    \n- Larger chunks: Fewer requests, faster upload for stable networks\n    \n- Each part is uploaded separately to S3, then combined\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid object_type, missing required fields, parent folder not found or deleted) |\n| 404 | Machine not found |\n| 450 | Storage full |\n| 451 | File already exists (when overwrite=false) |\n| 4710 | Permission required |\n\n### **Success Response Fields (File)**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | File ID (use this in complete endpoint) |\n| `uid` | String | Unique identifier for the file |\n| `upload_urls` | Array | Array of presigned S3 URLs for multipart upload. Each URL is for one chunk |\n| `upload_urls[].part_number` | Integer | Part number (starts from 1) |\n| `upload_urls[].url` | String | Presigned S3 URL for uploading this part |\n| `chunk_size` | Integer | Chunk size in MB used for upload |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Fields (Directory)**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | Integer | Directory ID |\n| `uid` | String | Unique identifier for the directory |\n| `upload_urls` | null | Always null for directories |\n| `chunk_size` | Integer | Chunk size (not used for directories) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Request Body Example**\n\n``` json\n{\n  \"file_name\": \"example.zip\",\n  \"object_type\": \"file\",\n  \"content_type\": \"application/zip\",\n  \"size\": 104857600,\n  \"chunk_size\": 250,\n  \"overwrite\": false,\n  \"parent_id\": 1\n}\n\n ```\n\n### **Success Response Example (File)**\n\n``` json\n{\n  \"id\": 6731,\n  \"uid\": \"string\",\n  \"upload_urls\": [\n    {\n      \"part_number\": 1,\n      \"url\": \"https://s3.amazonaws.com/bucket/file?uploadId=xyz&partNumber=1&X-Amz-Signature=...\"\n    },\n    {\n      \"part_number\": 2,\n      \"url\": \"https://s3.amazonaws.com/bucket/file?uploadId=xyz&partNumber=2&X-Amz-Signature=...\"\n    }\n  ],\n  \"chunk_size\": 250,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### **Success Response Example (Directory)**\n\n``` json\n{\n  \"id\": 124,\n  \"uid\": \"def456-ghi789-jkl012\",\n  \"upload_urls\": null,\n  \"chunk_size\": 250,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### **Upload Flow for Files**\n\n1. Call this endpoint to create file entry and get upload URLs\n    \n2. For each part in `upload_urls`:\n    \n    - Make PUT request to the URL with the file chunk data\n        \n    - Save the `ETag` header from the PUT response\n        \n3. Call `POST /files/:id/complete` with all part numbers and ETags to finalize upload\n    \n4. Directory creation is immediate (no upload needed)","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["file_name","object_type"],"properties":{"file_name":{"type":"string","description":"Name of the file or directory"},"object_type":{"type":"string","enum":["file","directory"],"description":"Type of object to create"},"content_type":{"type":"string","description":"MIME type of the file (required for files)"},"size":{"type":"integer","description":"File size in bytes (required for files)"},"chunk_size":{"type":"integer","description":"Chunk size for multipart upload in MB"},"overwrite":{"type":"boolean","description":"Whether to overwrite existing file with same name"},"parent_id":{"type":"integer","description":"Parent folder ID (root folder if omitted)"}}}}}}}}},"components":{"schemas":{"CreateFileResponse":{"type":"object","description":"Response after initiating a file upload","properties":{"id":{"type":"integer","description":"File ID"},"uid":{"type":"string","description":"Unique identifier for the upload"},"upload_urls":{"type":"array","nullable":true,"description":"Pre-signed URLs for uploading file chunks (null for directories)","items":{"$ref":"#/components/schemas/UploadUrl"}},"chunk_size":{"type":"integer","description":"Size of each chunk in MB"}}},"UploadUrl":{"type":"object","description":"Pre-signed URL for uploading a file chunk","properties":{"part_number":{"type":"integer","description":"Part number for multipart upload"},"url":{"type":"string","format":"uri","description":"Pre-signed URL for uploading this part"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error450Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error451Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Session Recordings Folder

> Lists session recording files and folders. Same structure as GET /files but scoped to session recordings. Optionally filter by machine\_id.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Query Parameters\
> \
> \| Parameter | Type | Description |\
> \| --- | --- | --- |\
> \| \`parent\_id\` | Integer | Parent folder ID. 0 = root folder |\
> \| \`page\` | Integer | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | Records per page. Default: 20 |\
> \| \`q\` | String | Search query. Searches by file/directory name |\
> \| \`machine\_id\` | Integer | (Optional) Filter recordings by machine ID |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Not found |\
> \| 403 | Forbidden |\
> \| 4710 | Permission required |\
> \
> \### Response Fields\
> \
> Same structure as GET /files. The response includes \`files\`, \`current\`, \`count\`, \`page\`, \`next\_page\`, \`client\_code\`, \`message\`, and \`timestamp\` fields.\
> \
> \### Response Example\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "5911",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "rec-20260121-214832.log",\
> &#x20;               "size": 14463,\
> &#x20;               "content\_type": "application/octet-stream",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": "/Session\_1950/rec-20260121-214832.log",\
> &#x20;               "parent\_id": 22086,\
> &#x20;               "last\_modified\_date": "2026-01-21T21:49:09.491Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "5910",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "rec-20260121-214832.mp4",\
> &#x20;               "size": 2095700,\
> &#x20;               "content\_type": "video/mp4",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": "/Session\_1950/rec-20260121-214832.mp4",\
> &#x20;               "parent\_id": 22086,\
> &#x20;               "last\_modified\_date": "2026-01-21T21:49:09.203Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": null,\
> &#x20;               "machine\_id": null\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "22086",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Session\_1950",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "directory",\
> &#x20;           "path": "/Session\_1950",\
> &#x20;           "parent\_id": 22049,\
> &#x20;           "last\_modified\_date": "2026-01-21T21:49:09.491Z",\
> &#x20;           "file\_storage\_size": null,\
> &#x20;           "file\_storage\_usage": null,\
> &#x20;           "user": null,\
> &#x20;           "machine\_id": null\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 2,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-16T10:21:33Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/recordings":{"get":{"summary":"List Session Recordings Folder","parameters":[{"name":"machine_id","in":"query","description":"(Optional) Filter session recordings by machine ID","schema":{"type":"integer"}},{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}}],"responses":{"200":{"description":"List of session recording files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error403Response"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Lists session recording files and folders. Same structure as GET /files but scoped to session recordings. Optionally filter by machine_id.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `parent_id` | Integer | Parent folder ID. 0 = root folder |\n| `page` | Integer | Page number. Default: 1 |\n| `per_page` | Integer | Records per page. Default: 20 |\n| `q` | String | Search query. Searches by file/directory name |\n| `machine_id` | Integer | (Optional) Filter recordings by machine ID |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Not found |\n| 403 | Forbidden |\n| 4710 | Permission required |\n\n### Response Fields\n\nSame structure as GET /files. The response includes `files`, `current`, `count`, `page`, `next_page`, `client_code`, `message`, and `timestamp` fields.\n\n### Response Example\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"5911\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"rec-20260121-214832.log\",\n                \"size\": 14463,\n                \"content_type\": \"application/octet-stream\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": \"/Session_1950/rec-20260121-214832.log\",\n                \"parent_id\": 22086,\n                \"last_modified_date\": \"2026-01-21T21:49:09.491Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        },\n        {\n            \"id\": \"5910\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"rec-20260121-214832.mp4\",\n                \"size\": 2095700,\n                \"content_type\": \"video/mp4\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": \"/Session_1950/rec-20260121-214832.mp4\",\n                \"parent_id\": 22086,\n                \"last_modified_date\": \"2026-01-21T21:49:09.203Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": null,\n                \"machine_id\": null\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"22086\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Session_1950\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"directory\",\n            \"path\": \"/Session_1950\",\n            \"parent_id\": 22049,\n            \"last_modified_date\": \"2026-01-21T21:49:09.491Z\",\n            \"file_storage_size\": null,\n            \"file_storage_usage\": null,\n            \"user\": null,\n            \"machine_id\": null\n        }\n    },\n    \"count\": 2,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-16T10:21:33Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error403Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## List Individual Files & Folders in Vagon Files

> Lists files and folders belonging to a specific machine.\
> \
> This endpoint allows you to browse the machine's file storage. You can navigate through folders using the \`parent\_id\` parameter.\
> \
> Pass \`task\_id\` to filter the response to folders associated with a specific task — the task's output/snapshot folder plus all session recording folders that were active under that task. Only directories are returned at  this level; clients descend via \`parent\_id\` to enumerate folder contents.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Machine ID |\
> \
> \### \*\*Query Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`parent\_id\` | Integer | No | Parent folder ID. 0 = root folder (machine's root folder) |\
> \| \`page\` | Integer | No | Page number. Default: 1 |\
> \| \`per\_page\` | Integer | No | Records per page. Default: 20 |\
> \| \`q\` | String | No | Search query. Searches by file/directory name |\
> \| \`task\_id\` | Integer | No | Filter to folders associated with the given task on the machine. Returns the task's output/snapshot folder plus linked session recording folders. Directories only. |\
> \
> \### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Machine not found, does not belong to organization, or \`task\_id\` does not belong to the machine |\
> \| 4710 | Permission required |\
> \### \*\*Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`files\` | Array | Array of file/folder objects |\
> \| \`files\[].id\` | String | File/folder ID |\
> \| \`files\[].type\` | String | Always "file" |\
> \| \`files\[].attributes.name\` | String | File or folder name |\
> \| \`files\[].attributes.size\` | Integer | File size in bytes. 0 for directories |\
> \| \`files\[].attributes.content\_type\` | String | MIME type (e.g., "image/png") or "directory" |\
> \| \`files\[].attributes.region\` | String | AWS region where file is stored |\
> \| \`files\[].attributes.status\` | String | File status (e.g., "upload\_completed") |\
> \| \`files\[].attributes.object\_type\` | String | Type: "file", "directory", or "root" |\
> \| \`files\[].attributes.path\` | String | Full path of the file/folder. null for some files |\
> \| \`files\[].attributes.parent\_id\` | Integer | Parent folder ID |\
> \| \`files\[].attributes.last\_modified\_date\` | String | ISO 8601 timestamp of last modification |\
> \| \`files\[].attributes.file\_storage\_size\` | Integer | Total file storage size for the machine (in bytes). null for non-root |\
> \| \`files\[].attributes.file\_storage\_usage\` | Integer | Used file storage for the machine (in bytes). null for non-root |\
> \| \`files\[].attributes.user\` | Object | User who owns the file |\
> \| \`files\[].attributes.user.id\` | String | User UUID |\
> \| \`files\[].attributes.user.type\` | String | Always "user" |\
> \| \`files\[].attributes.user.attributes.email\` | String | User email |\
> \| \`files\[].attributes.user.attributes.name\` | String | User name |\
> \| \`files\[].attributes.machine\_id\` | Integer | Machine ID the file belongs to |\
> \| \`current\` | Object | Current directory object (same structure as file objects). null if at root |\
> \| \`count\` | Integer | Total number of files/folders in current directory |\
> \| \`page\` | Integer | Current page number |\
> \| \`next\_page\` | Integer | Next page number. null if last page |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "files": \[\
> &#x20;       {\
> &#x20;           "id": "18468",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "Machine Project Folder",\
> &#x20;               "size": 0,\
> &#x20;               "content\_type": "directory",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "directory",\
> &#x20;               "path": "/Machine Project Folder",\
> &#x20;               "parent\_id": 18465,\
> &#x20;               "last\_modified\_date": "2026-02-05T10:20:53.650Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": {\
> &#x20;                   "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;                   "type": "user",\
> &#x20;                   "attributes": {\
> &#x20;                       "email": "<user@vagon.io>",\
> &#x20;                       "name": "Computer User"\
> &#x20;                   }\
> &#x20;               },\
> &#x20;               "machine\_id": 100\
> &#x20;           }\
> &#x20;       },\
> &#x20;       {\
> &#x20;           "id": "18473",\
> &#x20;           "type": "file",\
> &#x20;           "attributes": {\
> &#x20;               "name": "image.png",\
> &#x20;               "size": 303043,\
> &#x20;               "content\_type": "image/png",\
> &#x20;               "region": "dublin",\
> &#x20;               "status": "upload\_completed",\
> &#x20;               "object\_type": "file",\
> &#x20;               "path": null,\
> &#x20;               "parent\_id": 18465,\
> &#x20;               "last\_modified\_date": "2026-02-05T10:20:33.331Z",\
> &#x20;               "file\_storage\_size": null,\
> &#x20;               "file\_storage\_usage": null,\
> &#x20;               "user": {\
> &#x20;                   "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;                   "type": "user",\
> &#x20;                   "attributes": {\
> &#x20;                       "email": "<user@vagon.io>",\
> &#x20;                       "name": "Computer User"\
> &#x20;                   }\
> &#x20;               },\
> &#x20;               "machine\_id": 100\
> &#x20;           }\
> &#x20;       }\
> &#x20;   ],\
> &#x20;   "current": {\
> &#x20;       "id": "18465",\
> &#x20;       "type": "file",\
> &#x20;       "attributes": {\
> &#x20;           "name": "Computer #100",\
> &#x20;           "size": 0,\
> &#x20;           "content\_type": "directory",\
> &#x20;           "region": "dublin",\
> &#x20;           "status": "upload\_completed",\
> &#x20;           "object\_type": "root",\
> &#x20;           "path": null,\
> &#x20;           "parent\_id": null,\
> &#x20;           "last\_modified\_date": "2026-02-05T10:20:53.650Z",\
> &#x20;           "file\_storage\_size": 26843545600,\
> &#x20;           "file\_storage\_usage": 2688255,\
> &#x20;           "user": {\
> &#x20;               "id": "f1592625-edd0-48df-9bc0-de14910ec936",\
> &#x20;               "type": "user",\
> &#x20;               "attributes": {\
> &#x20;                   "email": "<user@vagon.io>",\
> &#x20;                   "name": "Computer User"\
> &#x20;               }\
> &#x20;           },\
> &#x20;           "machine\_id": 100\
> &#x20;       }\
> &#x20;   },\
> &#x20;   "count": 3,\
> &#x20;   "page": 1,\
> &#x20;   "next\_page": null,\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-05T10:22:33Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/machines/{id}/files":{"get":{"summary":"List Individual Files & Folders in Vagon Files","responses":{"200":{"description":"List of files and folders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Machine not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"parameters":[{"name":"parent_id","in":"query","description":"(Optional) Parent folder ID. 0 = root folder","schema":{"type":"string"}},{"name":"page","in":"query","description":"(Optional) Page number. Default: 1","schema":{"type":"integer"}},{"name":"per_page","in":"query","description":"(Optional) Records per page. Default: 20","schema":{"type":"integer"}},{"name":"q","in":"query","description":"(Optional) Search by file name","schema":{"type":"string"}},{"name":"task_id","in":"query","description":"(Optional) Filter to folders associated with a specific task on the machine. Returns the task's output/snapshot folder, all session recording folders linked to this task. Only directories are returned; descend via `parent_id` to fetch contents.","schema":{"type":"integer"}}],"tags":["Files"],"description":"Lists files and folders belonging to a specific machine.\n\nThis endpoint allows you to browse the machine's file storage. You can navigate through folders using the `parent_id` parameter.\n\nPass `task_id` to filter the response to folders associated with a specific task — the task's output/snapshot folder plus all session recording folders that were active under that task. Only directories are returned at  this level; clients descend via `parent_id` to enumerate folder contents.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Machine ID |\n\n### **Query Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `parent_id` | Integer | No | Parent folder ID. 0 = root folder (machine's root folder) |\n| `page` | Integer | No | Page number. Default: 1 |\n| `per_page` | Integer | No | Records per page. Default: 20 |\n| `q` | String | No | Search query. Searches by file/directory name |\n| `task_id` | Integer | No | Filter to folders associated with the given task on the machine. Returns the task's output/snapshot folder plus linked session recording folders. Directories only. |\n\n### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Machine not found, does not belong to organization, or `task_id` does not belong to the machine |\n| 4710 | Permission required |\n### **Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `files` | Array | Array of file/folder objects |\n| `files[].id` | String | File/folder ID |\n| `files[].type` | String | Always \"file\" |\n| `files[].attributes.name` | String | File or folder name |\n| `files[].attributes.size` | Integer | File size in bytes. 0 for directories |\n| `files[].attributes.content_type` | String | MIME type (e.g., \"image/png\") or \"directory\" |\n| `files[].attributes.region` | String | AWS region where file is stored |\n| `files[].attributes.status` | String | File status (e.g., \"upload_completed\") |\n| `files[].attributes.object_type` | String | Type: \"file\", \"directory\", or \"root\" |\n| `files[].attributes.path` | String | Full path of the file/folder. null for some files |\n| `files[].attributes.parent_id` | Integer | Parent folder ID |\n| `files[].attributes.last_modified_date` | String | ISO 8601 timestamp of last modification |\n| `files[].attributes.file_storage_size` | Integer | Total file storage size for the machine (in bytes). null for non-root |\n| `files[].attributes.file_storage_usage` | Integer | Used file storage for the machine (in bytes). null for non-root |\n| `files[].attributes.user` | Object | User who owns the file |\n| `files[].attributes.user.id` | String | User UUID |\n| `files[].attributes.user.type` | String | Always \"user\" |\n| `files[].attributes.user.attributes.email` | String | User email |\n| `files[].attributes.user.attributes.name` | String | User name |\n| `files[].attributes.machine_id` | Integer | Machine ID the file belongs to |\n| `current` | Object | Current directory object (same structure as file objects). null if at root |\n| `count` | Integer | Total number of files/folders in current directory |\n| `page` | Integer | Current page number |\n| `next_page` | Integer | Next page number. null if last page |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Response Example**\n\n``` json\n{\n    \"files\": [\n        {\n            \"id\": \"18468\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"Machine Project Folder\",\n                \"size\": 0,\n                \"content_type\": \"directory\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"directory\",\n                \"path\": \"/Machine Project Folder\",\n                \"parent_id\": 18465,\n                \"last_modified_date\": \"2026-02-05T10:20:53.650Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": {\n                    \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                    \"type\": \"user\",\n                    \"attributes\": {\n                        \"email\": \"user@vagon.io\",\n                        \"name\": \"Computer User\"\n                    }\n                },\n                \"machine_id\": 100\n            }\n        },\n        {\n            \"id\": \"18473\",\n            \"type\": \"file\",\n            \"attributes\": {\n                \"name\": \"image.png\",\n                \"size\": 303043,\n                \"content_type\": \"image/png\",\n                \"region\": \"dublin\",\n                \"status\": \"upload_completed\",\n                \"object_type\": \"file\",\n                \"path\": null,\n                \"parent_id\": 18465,\n                \"last_modified_date\": \"2026-02-05T10:20:33.331Z\",\n                \"file_storage_size\": null,\n                \"file_storage_usage\": null,\n                \"user\": {\n                    \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                    \"type\": \"user\",\n                    \"attributes\": {\n                        \"email\": \"user@vagon.io\",\n                        \"name\": \"Computer User\"\n                    }\n                },\n                \"machine_id\": 100\n            }\n        }\n    ],\n    \"current\": {\n        \"id\": \"18465\",\n        \"type\": \"file\",\n        \"attributes\": {\n            \"name\": \"Computer #100\",\n            \"size\": 0,\n            \"content_type\": \"directory\",\n            \"region\": \"dublin\",\n            \"status\": \"upload_completed\",\n            \"object_type\": \"root\",\n            \"path\": null,\n            \"parent_id\": null,\n            \"last_modified_date\": \"2026-02-05T10:20:53.650Z\",\n            \"file_storage_size\": 26843545600,\n            \"file_storage_usage\": 2688255,\n            \"user\": {\n                \"id\": \"f1592625-edd0-48df-9bc0-de14910ec936\",\n                \"type\": \"user\",\n                \"attributes\": {\n                    \"email\": \"user@vagon.io\",\n                    \"name\": \"Computer User\"\n                }\n            },\n            \"machine_id\": 100\n        }\n    },\n    \"count\": 3,\n    \"page\": 1,\n    \"next_page\": null,\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-05T10:22:33Z\"\n}\n\n ```"}}},"components":{"schemas":{"ListFilesResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"},{"type":"object","properties":{"files":{"type":"array","description":"List of files and folders","items":{"$ref":"#/components/schemas/FileObject"}},"current":{"$ref":"#/components/schemas/CurrentDirectory","description":"Current directory information"},"count":{"type":"integer","description":"Total number of items"},"page":{"type":"integer","description":"Current page number"},"next_page":{"type":"integer","nullable":true,"description":"Next page number (null if no more pages)"}}}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"FileObject":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"FileObjectAttributes":{"type":"object","properties":{"name":{"type":"string","description":"File or folder name"},"size":{"type":"integer","description":"File size in bytes (0 for directories)"},"content_type":{"type":"string","description":"MIME type of the file or \"directory\" for folders"},"region":{"type":"string","description":"Storage region"},"status":{"type":"string","enum":["pending_upload","upload_completed","upload_failed"],"description":"Upload status"},"object_type":{"type":"string","enum":["file","directory","root"],"description":"Type of object"},"path":{"type":"string","nullable":true,"description":"Path within the storage"},"parent_id":{"type":"integer","nullable":true,"description":"Parent folder ID"},"last_modified_date":{"type":"string","format":"date-time","nullable":true,"description":"Last modification timestamp"},"file_storage_size":{"type":"integer","nullable":true,"description":"Total storage size in bytes (only for root directories)"},"file_storage_usage":{"type":"integer","nullable":true,"description":"Used storage in bytes (only for root directories)"},"user":{"type":"object","nullable":true,"description":"User who owns this file/folder","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string"},"attributes":{"type":"object","properties":{"email":{"type":"string"},"name":{"type":"string"}}}}},"machine_id":{"type":"integer","nullable":true,"description":"Associated machine ID (for machine-scoped files)"}}},"CurrentDirectory":{"type":"object","description":"Current directory information with the same structure as FileObject","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/FileObjectAttributes"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Complete Upload

> Completes the multipart upload process for a file.\
> \
> After uploading all file chunks to the presigned S3 URLs, call this endpoint to finalize the upload and make the file available.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | File ID (returned from create endpoint) |\
> \
> \### \*\*Body Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`parts\` | Array | Yes | Array of uploaded parts with their ETags |\
> \| \`parts\[].part\_number\` | Integer | Yes | Part number (must match the part\_number from upload\_urls, starts from 1) |\
> \| \`parts\[].etag\` | String | Yes | ETag value returned from S3 PUT response header. Must include quotes. Example: \`"d8e8fca2dc0f896fd7cb4cb0031ba249"\` |\
> \
> \### \*\*About ETags\*\*\
> \
> \- When you PUT a chunk to S3, the response includes an \`ETag\` header\
> &#x20;   \
> \- Save this ETag exactly as returned (including the quotes)\
> &#x20;   \
> \- ETag format: \`"hexadecimal-string"\` (quotes are part of the value)\
> &#x20;   \
> \- Each part\_number must have a corresponding ETag\
> &#x20;   \
> \- Parts must be in order (part\_number 1, 2, 3, etc.)\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid parts format, file not found) |\
> \| 404 | File not found or does not belong to organization |\
> \| 450 | Storage limit exceeded after upload completion (file is deleted) |\
> \| 452 | File size mismatch - actual uploaded size doesn't match expected size (file is deleted) |\
> \| 4710 | Permission required |\
> \
> \### \*\*Request Body Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "parts": \[\
> &#x20;   {\
> &#x20;     "part\_number": 1,\
> &#x20;     "etag": "\\"d8e8fca2dc0f896fd7cb4cb0031ba249\\""\
> &#x20;   },\
> &#x20;   {\
> &#x20;     "part\_number": 2,\
> &#x20;     "etag": "\\"7cb4cb0031ba249d8e8fca2dc0f896fd\\""\
> &#x20;   }\
> &#x20; ]\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`uid\` | String | Unique identifier for the file |\
> \| \`download\_url\` | String | Presigned S3 URL for downloading the file. Valid for limited time (typically 1 hour) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### \*\*Success Response Example\*\*\
> \
> \`\`\` json\
> {\
> &#x20; "uid": "string",\
> &#x20; "download\_url": "<https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/{id}/complete":{"post":{"summary":"Complete Upload","responses":{"200":{"description":"Upload completed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"450":{"description":"Storage limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error450Response"}}}},"452":{"description":"File size mismatch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error452Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Completes the multipart upload process for a file.\n\nAfter uploading all file chunks to the presigned S3 URLs, call this endpoint to finalize the upload and make the file available.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | File ID (returned from create endpoint) |\n\n### **Body Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `parts` | Array | Yes | Array of uploaded parts with their ETags |\n| `parts[].part_number` | Integer | Yes | Part number (must match the part_number from upload_urls, starts from 1) |\n| `parts[].etag` | String | Yes | ETag value returned from S3 PUT response header. Must include quotes. Example: `\"d8e8fca2dc0f896fd7cb4cb0031ba249\"` |\n\n### **About ETags**\n\n- When you PUT a chunk to S3, the response includes an `ETag` header\n    \n- Save this ETag exactly as returned (including the quotes)\n    \n- ETag format: `\"hexadecimal-string\"` (quotes are part of the value)\n    \n- Each part_number must have a corresponding ETag\n    \n- Parts must be in order (part_number 1, 2, 3, etc.)\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid parts format, file not found) |\n| 404 | File not found or does not belong to organization |\n| 450 | Storage limit exceeded after upload completion (file is deleted) |\n| 452 | File size mismatch - actual uploaded size doesn't match expected size (file is deleted) |\n| 4710 | Permission required |\n\n### **Request Body Example**\n\n``` json\n{\n  \"parts\": [\n    {\n      \"part_number\": 1,\n      \"etag\": \"\\\"d8e8fca2dc0f896fd7cb4cb0031ba249\\\"\"\n    },\n    {\n      \"part_number\": 2,\n      \"etag\": \"\\\"7cb4cb0031ba249d8e8fca2dc0f896fd\\\"\"\n    }\n  ]\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `uid` | String | Unique identifier for the file |\n| `download_url` | String | Presigned S3 URL for downloading the file. Valid for limited time (typically 1 hour) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### **Success Response Example**\n\n``` json\n{\n  \"uid\": \"string\",\n  \"download_url\": \"https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...&X-Amz-Expires=3600\",\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["parts"],"properties":{"parts":{"type":"array","description":"List of uploaded parts with their ETags","items":{"type":"object","required":["part_number","etag"],"properties":{"part_number":{"type":"integer","description":"Part number (1-indexed)"},"etag":{"type":"string","description":"ETag returned from S3 upload"}}}}}}}}}}}},"components":{"schemas":{"CompleteUploadResponse":{"type":"object","description":"Response after completing a multipart upload","properties":{"uid":{"type":"string","description":"Unique identifier of the uploaded file"},"download_url":{"type":"string","format":"uri","description":"URL to download the uploaded file"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error450Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error452Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Delete File from Vagon Files

> Deletes a file or directory. When a directory is deleted, all files and subdirectories inside it are also deleted recursively. This action is irreversible.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### \*\*Path Parameters\*\*\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | File or Directory ID |\
> \
> \### \*\*Deletion Process\*\*\
> \
> \- Files: Immediately marked as deleted and removed from S3\
> &#x20;   \
> \- Directories: Recursively deletes all child files and subdirectories\
> &#x20;   \
> &#x20;   \- Deletion happens asynchronously via background job\
> &#x20;       \
> &#x20;   \- All nested content is soft-deleted\
> &#x20;       \
> &#x20;   \- S3 objects are removed\
> &#x20;       \
> \
> \#### \*\*Error Responses\*\*\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | File/directory not found or does not belong to organization |\
> \| 450 | Attempted to delete root folder |\
> \| 4710 | Permission required |\
> \
> \#### \*\*Success Response\*\*\
> \
> \`\`\` json\
> {\
> &#x20;   "client\_code": 200,\
> &#x20;   "message": "OK",\
> &#x20;   "timestamp": "2026-02-04T12:16:26Z"\
> }\
> \
> &#x20;\`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/{id}":{"delete":{"summary":"Delete File from Vagon Files","responses":{"200":{"description":"File deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Deletes a file or directory. When a directory is deleted, all files and subdirectories inside it are also deleted recursively. This action is irreversible.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### **Path Parameters**\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | File or Directory ID |\n\n### **Deletion Process**\n\n- Files: Immediately marked as deleted and removed from S3\n    \n- Directories: Recursively deletes all child files and subdirectories\n    \n    - Deletion happens asynchronously via background job\n        \n    - All nested content is soft-deleted\n        \n    - S3 objects are removed\n        \n\n#### **Error Responses**\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | File/directory not found or does not belong to organization |\n| 450 | Attempted to delete root folder |\n| 4710 | Permission required |\n\n#### **Success Response**\n\n``` json\n{\n    \"client_code\": 200,\n    \"message\": \"OK\",\n    \"timestamp\": \"2026-02-04T12:16:26Z\"\n}\n\n ```"}}},"components":{"schemas":{"SuccessResponse":{"allOf":[{"$ref":"#/components/schemas/BaseResponse"}]},"BaseResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Generate Download Link for File

> Creates download link for files or directory contents to let users create download links.\
> \
> This endpoint allows you to download single/multiple file(s)s or an entire directory.\
> \
> \- For single file downloads, it returns a direct download URL.\
> &#x20;   \
> \- For multiple files or directories, it returns a download ID that can be used to check the status.\
> &#x20;   \
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Body Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`directory\_id\` | Integer | No | Directory ID to download recursively. Zips the entire directory and all subdirectories |\
> \| \`file\_ids\` | Array\\\[Integer\\] | No | Array of file IDs to be downloaded. |\
> \| \`task\_id\` | Integer | No | Task ID. Bundles the task's output folder and every session recording folder linked to that task (across seat and admin storage) into a single ZIP. Each input directory becomes a top-level subfolder in the archive named after the directory. |\
> \
> \### Notes\
> \
> \- Exactly one of \`directory\_id\`, \`file\_ids\`, or \`task\_id\` must be provided. Sending more than one (or none) returns \`4722\`.\
> \- For single file downloads (one file\_id), returns a direct download URL immediately\
> \- For multiple files, directories, or \`task\_id\`, returns a \`download\_id\` that must be used with \`GET /files/downloads/:id\` to check status and get download URL\
> \- Multiple file downloads, directory downloads, and \`task\_id\` downloads require the organization to have \`multiple\_file\_download\` feature enabled\
> &#x20;   \
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request (e.g., invalid IDs) |\
> \| 404 | Directory or files not found or do not belong to organization |\
> \| 4710 | Permission required (multiple file download not enabled) |\
> \| 4717 | Directory or file not found |\
> \| 4718 | File count mismatch during download (requested files not found) |\
> \| 4719 | Directory is empty or has no completed files |\
> \| 4720 | Download URL generation failed |\
> \| 4722 | None of \`directory\_id\`, \`file\_ids\`, \`task\_id\` provided — or more than one provided (mutually exclusive) |\
> \
> \### \*\*Request Body Example\*\*\
> \
> Provide exactly one of \`directory\_id\`, \`file\_ids\`, or \`task\_id\`. Remove the unused fields before sending — they are shown together below for reference only and are mutually exclusive.\
> \
> \`\`\` json\
> {\
> &#x20; "directory\_id": 1,\
> &#x20; "file\_ids": \[2, 3],\
> &#x20; "task\_id": 42\
> }\
> \
> &#x20;\`\`\`\
> \
> \### \*\*Success Response Fields\*\*\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`url\` | String | Presigned S3 download URL (for single file download) |\
> \| \`size\` | Integer | File size in bytes (single file). For multiple files or directory, total size in bytes of all files to be zipped |\
> \| \`name\` | String | File name |\
> \| \`content\_type\` | String | MIME type of the file |\
> \| \`download\_id\` | Integer | Download ID (for multiple files/directory - use with GET /files/downloads/:id) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Success Response Example\
> \
> When downloading a single file, returns direct download URL. When downloading multiple files or a directory, returns download ID.\
> \
> \`\`\` json\
> {\
> &#x20; "url": "<https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20; "size": 1601,\
> &#x20; "name": "string",\
> &#x20; "content\_type": "string",\
> &#x20; "download\_id": 5085,\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Usage Flow\
> \
> 1\. Call this endpoint with \`directory\_id\` or \`file\_ids\`\
> &#x20;   \
> 2\. If single file: Use the returned \`url\` directly to download\
> &#x20;   \
> 3\. If multiple files/directory: Use the returned \`download\_id\` with \`GET /files/downloads/:id\` to:\
> &#x20;   \- Check processing status (pending, processing, uploaded, failed, cancelled)\
> &#x20;       \
> &#x20;   \- Get download URL when status is \`uploaded\`\
> &#x20;       \
> 4\. Download URLs expire after 24 hours

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/download":{"post":{"summary":"Generate Download Link for File","responses":{"200":{"description":"Download link generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadLinkResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"File or directory not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4717":{"description":"Directory or file not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4717Response"}}}},"4718":{"description":"File count mismatch during download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4718Response"}}}},"4719":{"description":"Directory is empty or has no completed files","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4719Response"}}}},"4720":{"description":"Download URL generation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4720Response"}}}},"4722":{"description":"No files or directory provided for download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4722Response"}}}}},"tags":["Files"],"description":"Creates download link for files or directory contents to let users create download links.\n\nThis endpoint allows you to download single/multiple file(s)s or an entire directory.\n\n- For single file downloads, it returns a direct download URL.\n    \n- For multiple files or directories, it returns a download ID that can be used to check the status.\n    \n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Body Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `directory_id` | Integer | No | Directory ID to download recursively. Zips the entire directory and all subdirectories |\n| `file_ids` | Array\\[Integer\\] | No | Array of file IDs to be downloaded. |\n| `task_id` | Integer | No | Task ID. Bundles the task's output folder and every session recording folder linked to that task (across seat and admin storage) into a single ZIP. Each input directory becomes a top-level subfolder in the archive named after the directory. |\n\n### Notes\n\n- Exactly one of `directory_id`, `file_ids`, or `task_id` must be provided. Sending more than one (or none) returns `4722`.\n- For single file downloads (one file_id), returns a direct download URL immediately\n- For multiple files, directories, or `task_id`, returns a `download_id` that must be used with `GET /files/downloads/:id` to check status and get download URL\n- Multiple file downloads, directory downloads, and `task_id` downloads require the organization to have `multiple_file_download` feature enabled\n    \n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request (e.g., invalid IDs) |\n| 404 | Directory or files not found or do not belong to organization |\n| 4710 | Permission required (multiple file download not enabled) |\n| 4717 | Directory or file not found |\n| 4718 | File count mismatch during download (requested files not found) |\n| 4719 | Directory is empty or has no completed files |\n| 4720 | Download URL generation failed |\n| 4722 | None of `directory_id`, `file_ids`, `task_id` provided — or more than one provided (mutually exclusive) |\n\n### **Request Body Example**\n\nProvide exactly one of `directory_id`, `file_ids`, or `task_id`. Remove the unused fields before sending — they are shown together below for reference only and are mutually exclusive.\n\n``` json\n{\n  \"directory_id\": 1,\n  \"file_ids\": [2, 3],\n  \"task_id\": 42\n}\n\n ```\n\n### **Success Response Fields**\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `url` | String | Presigned S3 download URL (for single file download) |\n| `size` | Integer | File size in bytes (single file). For multiple files or directory, total size in bytes of all files to be zipped |\n| `name` | String | File name |\n| `content_type` | String | MIME type of the file |\n| `download_id` | Integer | Download ID (for multiple files/directory - use with GET /files/downloads/:id) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Success Response Example\n\nWhen downloading a single file, returns direct download URL. When downloading multiple files or a directory, returns download ID.\n\n``` json\n{\n  \"url\": \"https://s3.amazonaws.com/bucket/file?X-Amz-Signature=...&X-Amz-Expires=3600\",\n  \"size\": 1601,\n  \"name\": \"string\",\n  \"content_type\": \"string\",\n  \"download_id\": 5085,\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### Usage Flow\n\n1. Call this endpoint with `directory_id` or `file_ids`\n    \n2. If single file: Use the returned `url` directly to download\n    \n3. If multiple files/directory: Use the returned `download_id` with `GET /files/downloads/:id` to:\n    - Check processing status (pending, processing, uploaded, failed, cancelled)\n        \n    - Get download URL when status is `uploaded`\n        \n4. Download URLs expire after 24 hours","requestBody":{"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["directory_id"],"properties":{"directory_id":{"type":"integer","description":"Directory ID to download recursively. Zips the entire directory and all subdirectories."}},"additionalProperties":false},{"type":"object","required":["file_ids"],"properties":{"file_ids":{"type":"array","description":"List of file IDs to download.","items":{"type":"integer"}}},"additionalProperties":false},{"type":"object","required":["task_id"],"properties":{"task_id":{"type":"integer","description":"Task ID. Bundles the task's output folder and all linked session recording folders into a single ZIP."}},"additionalProperties":false}]}}}}}}},"components":{"schemas":{"DownloadLinkResponse":{"type":"object","description":"Response containing download link information","properties":{"url":{"type":"string","format":"uri","nullable":true,"description":"Download URL (null if still processing)"},"size":{"type":"integer","nullable":true,"description":"File size in bytes"},"name":{"type":"string","nullable":true,"description":"File name"},"content_type":{"type":"string","nullable":true,"description":"MIME type of the file"},"download_id":{"type":"integer","nullable":true,"description":"Download job ID for status tracking"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4717Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4718Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4719Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4720Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4722Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Get Download Status

> Retrieves the status and download URL for a file download.\
> \
> This endpoint is used to check the processing status of a file created via \`POST /files/download\`. The file is created asynchronously, so you need to poll this endpoint until the status is \`uploaded\`.\
> \
> \### Headers\
> \
> \| Name | Type |\
> \| --- | --- |\
> \| Authorization\\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\
> \| Content-Type | application/json |\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Temporary file ID (download\_id returned from POST /files/download) |\
> \
> \### Status Values\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| \`pending\` | File creation is queued but not started |\
> \| \`processing\` | File is being created |\
> \| \`uploaded\` | File is ready for download |\
> \| \`failed\` | File creation failed |\
> \
> \### Error Responses\
> \
> \| Status | Description |\
> \| --- | --- |\
> \| 400 | Bad request |\
> \| 404 | Temporary file not found, expired, or does not belong to organization |\
> \| 4710 | Permission required |\
> \### Response Fields\
> \
> \| Field | Type | Description |\
> \| --- | --- | --- |\
> \| \`id\` | String | Temporary file ID |\
> \| \`type\` | String | Always \`"download"\` |\
> \| \`attributes.status\` | String | Current status: \`pending\`, \`processing\`, \`uploaded\`, \`failed\` |\
> \| \`attributes.download\_url\` | String | Presigned S3 download URL. Only present when status is \`uploaded\` and \`generate\_download\_url\` is true. Valid for limited time (typically 1 hour) |\
> \| \`attributes.expires\_at\` | String | ISO 8601 timestamp when the temporary file will be deleted (typically 24 hours after creation) |\
> \| \`attributes.size\` | Integer | Total size in bytes of the files or directory being zipped (nullable for older records) |\
> \| \`client\_code\` | Integer | Response code (200 for success) |\
> \| \`message\` | String | Response message |\
> \| \`timestamp\` | String | Response timestamp (ISO 8601) |\
> \
> \### Success Response\
> \
> \`\`\` json\
> {\
> &#x20; "id": "string",\
> &#x20; "type": "download",\
> &#x20; "attributes": {\
> &#x20;   "status": "uploaded",\
> &#x20;   "download\_url": "<https://s3.amazonaws.com/bucket/temp\\_files/uuid/archive.zip?X-Amz-Signature=...\\&X-Amz-Expires=3600",\\>
> &#x20;   "expires\_at": "2021-01-21T16:09:09.461Z",\
> &#x20;   "size": 1048576\
> &#x20; },\
> &#x20; "client\_code": 200,\
> &#x20; "message": "OK",\
> &#x20; "timestamp": "2026-02-05T10:00:00Z"\
> }\
> \
> &#x20;\`\`\`\
> \
> \### Usage Flow\
> \
> 1\. Call \`POST /files/download\` with \`directory\_id\` or \`file\_ids\` to get a \`download\_id\`\
> &#x20;   \
> 2\. Poll this endpoint with the \`download\_id\` to check status\
> &#x20;   \
> 3\. When status is \`uploaded\`, use the \`download\_url\` to download the zip file\
> &#x20;   \
> 4\. Temporary files expire after 24 hours\
> 5\. To cancel a pending download, use \`DELETE /files/downloads/:id\`

````json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/downloads/{id}":{"get":{"summary":"Get Download Status","responses":{"200":{"description":"Download status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadStatusResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Download not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}}},"tags":["Files"],"description":"Retrieves the status and download URL for a file download.\n\nThis endpoint is used to check the processing status of a file created via `POST /files/download`. The file is created asynchronously, so you need to poll this endpoint until the status is `uploaded`.\n\n### Headers\n\n| Name | Type |\n| --- | --- |\n| Authorization\\* | HMAC {key}:{signature}:{nonce}:{timestamp} |\n| Content-Type | application/json |\n\n### Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Temporary file ID (download_id returned from POST /files/download) |\n\n### Status Values\n\n| Status | Description |\n| --- | --- |\n| `pending` | File creation is queued but not started |\n| `processing` | File is being created |\n| `uploaded` | File is ready for download |\n| `failed` | File creation failed |\n\n### Error Responses\n\n| Status | Description |\n| --- | --- |\n| 400 | Bad request |\n| 404 | Temporary file not found, expired, or does not belong to organization |\n| 4710 | Permission required |\n### Response Fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `id` | String | Temporary file ID |\n| `type` | String | Always `\"download\"` |\n| `attributes.status` | String | Current status: `pending`, `processing`, `uploaded`, `failed` |\n| `attributes.download_url` | String | Presigned S3 download URL. Only present when status is `uploaded` and `generate_download_url` is true. Valid for limited time (typically 1 hour) |\n| `attributes.expires_at` | String | ISO 8601 timestamp when the temporary file will be deleted (typically 24 hours after creation) |\n| `attributes.size` | Integer | Total size in bytes of the files or directory being zipped (nullable for older records) |\n| `client_code` | Integer | Response code (200 for success) |\n| `message` | String | Response message |\n| `timestamp` | String | Response timestamp (ISO 8601) |\n\n### Success Response\n\n``` json\n{\n  \"id\": \"string\",\n  \"type\": \"download\",\n  \"attributes\": {\n    \"status\": \"uploaded\",\n    \"download_url\": \"https://s3.amazonaws.com/bucket/temp_files/uuid/archive.zip?X-Amz-Signature=...&X-Amz-Expires=3600\",\n    \"expires_at\": \"2021-01-21T16:09:09.461Z\",\n    \"size\": 1048576\n  },\n  \"client_code\": 200,\n  \"message\": \"OK\",\n  \"timestamp\": \"2026-02-05T10:00:00Z\"\n}\n\n ```\n\n### Usage Flow\n\n1. Call `POST /files/download` with `directory_id` or `file_ids` to get a `download_id`\n    \n2. Poll this endpoint with the `download_id` to check status\n    \n3. When status is `uploaded`, use the `download_url` to download the zip file\n    \n4. Temporary files expire after 24 hours\n5. To cancel a pending download, use `DELETE /files/downloads/:id`"}}},"components":{"schemas":{"DownloadStatusResponse":{"type":"object","description":"Download job status response","properties":{"id":{"type":"string"},"type":{"type":"string"},"attributes":{"$ref":"#/components/schemas/DownloadStatusAttributes"}}},"DownloadStatusAttributes":{"type":"object","description":"Download job status attributes","properties":{"status":{"type":"string","enum":["pending","processing","uploaded","failed","cancelled"],"description":"Current status of the download job"},"download_url":{"type":"string","format":"uri","nullable":true,"description":"Download URL (available when status is uploaded)"},"expires_at":{"type":"string","format":"date-time","description":"Expiration timestamp for the download URL"},"size":{"type":"integer","nullable":true,"description":"Total size in bytes of the files or directory being zipped"}}},"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
````

## Abort Pending Download

> Aborts a pending or processing zip download. Use the same \`id\` (download\_id) as returned from POST /files/download and used with GET /files/downloads/:id. When status is \`processing\`, the running job will stop and abort the S3 multipart upload.\
> \
> \### Path Parameters\
> \
> \| Parameter | Type | Required | Description |\
> \| --- | --- | --- | --- |\
> \| \`id\` | Integer | Yes | Temporary file ID (download\_id from POST /files/download) |\
> \
> \### Notes\
> \
> \- Both \`pending\` and \`processing\` downloads can be aborted. If the download is already \`uploaded\`, \`failed\`, or \`cancelled\`, the API returns 4716.\
> \- After abort, the temporary file is marked as \`cancelled\` and will not be processed.

```json
{"openapi":"3.0.0","info":{"title":"Vagon Computers API","version":"1.0.6"},"servers":[{"url":"https://api.vagon.io/organization-management/v1"}],"paths":{"/files/downloads/{id}":{"delete":{"summary":"Abort Pending Download","operationId":"abortDownload","responses":{"200":{"description":"Download aborted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptySuccessResponse"}}}},"400":{"description":"Bad request (e.g. download cannot be aborted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error400Response"}}}},"404":{"description":"Download not found or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error404Response"}}}},"4710":{"description":"Permission required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4710Response"}}}},"4716":{"description":"Download cannot be aborted (already uploaded or failed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error4716Response"}}}}},"tags":["Files"],"description":"Aborts a pending or processing zip download. Use the same `id` (download_id) as returned from POST /files/download and used with GET /files/downloads/:id. When status is `processing`, the running job will stop and abort the S3 multipart upload.\n\n### Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | Integer | Yes | Temporary file ID (download_id from POST /files/download) |\n\n### Notes\n\n- Both `pending` and `processing` downloads can be aborted. If the download is already `uploaded`, `failed`, or `cancelled`, the API returns 4716.\n- After abort, the temporary file is marked as `cancelled` and will not be processed.","parameters":[{"name":"id","in":"path","required":true,"description":"(Required) Temporary file ID (download_id from POST /files/download)","schema":{"type":"integer"}}]}}},"components":{"schemas":{"Error400Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"ErrorResponse":{"type":"object","properties":{"client_code":{"type":"integer"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"Error404Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4710Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]},"Error4716Response":{"allOf":[{"$ref":"#/components/schemas/ErrorResponse"}]}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vagon.io/teams/reference/files.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
