# Files

You can use the API to download and upload binary files. The API supports three types of file uploads: chat files (with automatic expiration), project assets, and user/bot avatars.

## File Upload Types

* **Chat files**: Files uploaded during conversations. These have automatic expiration (default: 30 days).
* **Assets**: Project assets that can be used across the platform. These have no expiration by default, but can be set via query parameter. Images automatically generate thumbnails.
* **Avatars**: User profile photos or bot avatars. These have no expiration and are stored in a fixed path structure.

## Upload a project asset

<mark style="color:green;">`POST`</mark> `https://api.tiledesk.com/v3/:project_id/files/assets`

Uploads a file as a project asset. Assets have no expiration by default, but can be set via query parameter.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| project\_id | string | The Project Id is a unique code assigned to your project when you create it in Tiledesk. |

#### Query Parameters

| Name       | Type   | Description                                                                                                 |
| ---------- | ------ | ----------------------------------------------------------------------------------------------------------- |
| expiration | number | Optional. Expiration time in seconds. If provided and greater than 0, the file will expire after this time. |

#### Headers

| Name          | Type   | Description                                                 |
| ------------- | ------ | ----------------------------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT. Minimum role: admin |
| Content-Type  | string | Use "multipart/form-data" value                             |

#### Request Body

| Name | Type   | Description                                                                                                         |
| ---- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| file | binary | The binary file to upload. Must match allowed extensions for assets. Images will automatically generate thumbnails. |

{% tabs %}
{% tab title="201 File uploaded successfully" %}

```
{
  "message": "File uploaded successfully",
  "filename": "uploads/projects/5ebd890292befe0019054973/files/uuid/logo.png",
  "thumbnail": "uploads/projects/5ebd890292befe0019054973/files/uuid/thumbnails_200_200-logo.png"
}
```

{% endtab %}

{% tab title="400 Bad request - Invalid file or upload error" %}

```
{
  "success": false,
  "error": "Error message"
  "code": "Error code" // code is not always returned
}
```

{% endtab %}

{% tab title="403 Forbidden - File extension not allowed or content verification failed" %}

```
{
  "success": false,
  "error": "File extension .exe is not allowed"
}
```

{% endtab %}

{% tab title="413 File too large" %}

```
{
  "success": false,
  "error": "File too large",
  "code": "LIMIT_FILE_SIZE"
}
```

{% endtab %}
{% endtabs %}

Example:

```
curl -v -X POST \
  -H 'Content-Type: multipart/form-data' \
  -u user@example.com:password \
  -F file=@logo.png \
  https://api.tiledesk.com/v3/files/assets?expiration=86400
```

## Upload a chat file

<mark style="color:green;">`POST`</mark> `https://api.tiledesk.com/v3/:project_id/files/chat`

Uploads a file for use in chat conversations. The file will automatically expire after a configured time (default: 30 days).

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| project\_id | string | The Project Id is a unique code assigned to your project when you create it in Tiledesk. |

#### Headers

| Name          | Type   | Description                             |
| ------------- | ------ | --------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT. |
| Content-Type  | string | Use "multipart/form-data" value         |

#### Request Body

| Name | Type   | Description                |
| ---- | ------ | -------------------------- |
| file | binary | The binary file to upload. |

{% tabs %}
{% tab title="201 File uploaded successfully" %}

```
{
  "message": "File uploaded successfully",
  "filename": "uploads/projects/5ebd890292befe0019054973/files/uuid/document.pdf"
}
```

{% endtab %}

{% tab title="400 Bad request - Invalid file or upload error" %}

```
{
  "success": false,
  "error": "Error message",
  "code": "Error code"
}
```

{% endtab %}

{% tab title="403 Forbidden - File extension not allowed or content verification failed" %}

```
{
  "success": false,
  "error": "File extension .exe is not allowed"
}
```

{% endtab %}

{% tab title="413 File too large" %}

```
{
  "success": false,
  "error": "File too large",
  "code": "LIMIT_FILE_SIZE"
}
```

{% endtab %}
{% endtabs %}

Example:

```
curl -v -X POST \
  -H 'Content-Type: multipart/form-data' \
  -u user@example.com:password \
  -F file=@document.pdf \
  https://api.tiledesk.com/v3/files/chat
```

## Upload user profile photo or bot avatar

<mark style="color:green;">`POST`</mark> `https://api.tiledesk.com/v3/:project_id/files/users/photo`

Uploads a profile photo for a user or avatar for a bot. Only image files are allowed (`.png`, `.jpg`, `.jpeg`, `.gif`). The file is stored in a fixed path structure: `uploads/users/{user_id|bot_id}/images/photo.jpg`. Automatically generates a 200x200 thumbnail. Requires agent role or bot/subscription authentication.

#### Path Parameters

| Name        | Type   | Description                                                                              |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| project\_id | string | The Project Id is a unique code assigned to your project when you create it in Tiledesk. |

#### Query Parameters

| Name    | Type   | Description                                                                                                                             |
| ------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| bot\_id | string | Optional. If provided, uploads the avatar for the specified bot. The authenticated user must be an admin or owner of the bot's project. |

#### Headers

| Name          | Type   | Description                                                 |
| ------------- | ------ | ----------------------------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT. Minimum role: agent |
| Content-Type  | string | Use "multipart/form-data" value                             |

#### Request Body

| Name | Type   | Description                                                               |
| ---- | ------ | ------------------------------------------------------------------------- |
| file | binary | The image file to upload. Must be one of: `.png`, `.jpg`, `.jpeg`, `.gif` |

{% tabs %}
{% tab title="201 Image uploaded successfully" %}

```
{
  "message": "Image uploaded successfully",
  "filename": "uploads/users/5ebd890292befe0019054973/images/photo.jpg",
  "thumbnail": "uploads/users/5ebd890292befe0019054973/images/thumbnails_200_200-photo.jpg"
}
```

{% endtab %}

{% tab title="400 Bad request - No file uploaded or invalid file" %}

```
{
  "success": false,
  "error": "No file uploaded"
}
```

{% endtab %}

{% tab title="401 Unauthorized - User doesn" %}

```
{
  "success": false,
  "error": "You don't belong to the chatbot's project"
}
```

{% endtab %}

{% tab title="403 Forbidden - Insufficient permissions or file extension not allowed" %}

```
{
  "success": false,
  "error": "You don't have the role required to modify the chatbot"
}
```

{% endtab %}

{% tab title="404 Chatbot not found" %}

```
{
  "success": false,
  "error": "Chatbot not found"
}
```

{% endtab %}

{% tab title="413 File too large" %}

```
{
  "success": false,
  "error": "File too large",
  "code": "LIMIT_FILE_SIZE"
}
```

{% endtab %}
{% endtabs %}

Example (user photo):

```
curl -v -X POST \
  -H 'Content-Type: multipart/form-data' \
  -u user@example.com:password \
  -F file=@photo.jpg \
  https://api.tiledesk.com/v3/files/users/photo
```

Example (bot avatar):

```
curl -v -X POST \
  -H 'Content-Type: multipart/form-data' \
  -u user@example.com:password \
  -F file=@bot_avatar.png \
  https://api.tiledesk.com/v3/files/users/photo?bot_id=65c5f3599faf2d04cd7da528
```

## Get the binary file as stream by filename path

<mark style="color:blue;">`GET`</mark> `https://api.tiledesk.com/v3/files`

Retrieves a file as a stream by its path. The file is returned with appropriate Content-Type headers. If the file is not found in the primary storage, the system automatically falls back to a secondary storage service.

#### Query Parameters

| Name           | Type    | Description                                                                                                      |
| -------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| path           | string  | The file path (URL encoded). Example: `uploads/projects/5ebd890292befe0019054973/files/uuid/document.pdf`        |
| as\_attachment | boolean | Optional. If set, the file will be returned with Content-Disposition header set to attachment, forcing download. |

#### Headers

| Name          | Type   | Description                            |
| ------------- | ------ | -------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT |

{% tabs %}
{% tab title="200 File stream" %}

```
<binary content>
```

{% endtab %}

{% tab title="404 File not found" %}

```
{
  "success": false,
  "error": "File not found."
}
```

{% endtab %}

{% tab title="500 Error getting file" %}

```
{
  "success": false,
  "error": "Error getting file."
}
```

{% endtab %}
{% endtabs %}

Example:

```
curl -v -X GET \
  -u user@example.com:password \
  "https://api.tiledesk.com/v3/files?path=uploads%2Fprojects%2F5ebd890292befe0019054973%2Ffiles%2Fuuid%2Fdocument.pdf"
```

Example (as attachment):

```
curl -v -X GET \
  -u user@example.com:password \
  "https://api.tiledesk.com/v3/files?path=uploads%2Fprojects%2F5ebd890292befe0019054973%2Ffiles%2Fuuid%2Fdocument.pdf&as_attachment=true"
```

## Download the binary file by filename path

<mark style="color:blue;">`GET`</mark> `https://api.tiledesk.com/v3/files/download`

Downloads a file by its path. The file is returned with Content-Disposition header set to attachment, forcing download with the original filename.

#### Query Parameters

| Name | Type   | Description                                                                                               |
| ---- | ------ | --------------------------------------------------------------------------------------------------------- |
| path | string | The file path (URL encoded). Example: `uploads/projects/5ebd890292befe0019054973/files/uuid/document.pdf` |

#### Headers

| Name          | Type   | Description                            |
| ------------- | ------ | -------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT |

{% tabs %}
{% tab title="200 File download" %}

```
<binary content>
```

{% endtab %}

{% tab title="404 File not found" %}

```
{
  "success": false,
  "error": "File not found."
}
```

{% endtab %}

{% tab title="500 Error getting file" %}

```
{
  "success": false,
  "error": "Error getting file."
}
```

{% endtab %}
{% endtabs %}

Example:

```
curl -v -X GET \
  -u user@example.com:password \
  "https://api.tiledesk.com/v3/files/download?path=uploads%2Fprojects%2F5ebd890292befe0019054973%2Ffiles%2Fuuid%2Fdocument.pdf"
```

## Delete a file

<mark style="color:red;">`DELETE`</mark> `https://api.tiledesk.com/v3/files`

Deletes a file by its path. If the file is an image, the associated thumbnail (if exists) will also be deleted automatically. The system checks both primary and fallback storage services.

#### Query Parameters

| Name | Type   | Description                                                                                                                                                        |
| ---- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| path | string | The file path (URL encoded). Example: `uploads/users/65c5f3599faf2d04cd7da528/images/photo.jpg` or `uploads/projects/65c5f3599faf2d04cd7da528/files/uuid/logo.png` |

#### Headers

| Name          | Type   | Description                            |
| ------------- | ------ | -------------------------------------- |
| Authorization | string | Authorization token. Basic Auth or JWT |

{% tabs %}
{% tab title="200 File deleted successfully" %}

```
{
  "message": "File deleted successfully",
  "filename": "uploads/users/65c5f3599faf2d04cd7da528/images/photo.jpg"
}
```

{% endtab %}

{% tab title="400 Bad request - Path parameter missing or invalid" %}

```
{
  "success": false,
  "error": "Path parameter is required"
}
```

{% endtab %}

{% tab title="404 File not found" %}

```
{
  "success": false,
  "error": "File not found."
}
```

{% endtab %}

{% tab title="500 Error deleting file" %}

```
{
  "success": false,
  "error": "Error deleting file."
}
```

{% endtab %}
{% endtabs %}

Example (delete user photo):

```
curl -v -X DELETE \
  -u user@example.com:password \
  "https://api.tiledesk.com/v3/files?path=uploads%2Fusers%2F65c5f3599faf2d04cd7da528%2Fimages%2Fphoto.jpg"
```

Example (delete project asset):

```
curl -v -X DELETE \
  -u user@example.com:password \
  "https://api.tiledesk.com/v3/files?path=uploads%2Fprojects%2F65c5f3599faf2d04cd7da528%2Ffiles%2Fuuid%2Flogo.png"
```

## Error Codes

* **400**: Bad request - Invalid file, missing parameters, or upload error
* **403**: Forbidden - File extension not allowed, content verification failed, or insufficient permissions
* **404**: Not found - File or resource not found
* **413**: Payload too large - File exceeds maximum upload size (configurable via `MAX_UPLOAD_FILE_SIZE` environment variable)
* **500**: Internal server error - Server error during file operations

## File Content Verification

All uploaded files are verified to ensure the file content matches the declared MIME type. This prevents security issues by detecting mismatched file types.

## Thumbnail Generation

Images uploaded as assets or user/bot avatars automatically generate 200x200 pixel thumbnails. Thumbnails are stored with the pattern `thumbnails_200_200-{original_filename}` and are automatically deleted when the main file is deleted.
