---
source_url: https://www.pubnub.com/docs/chat/kotlin-chat-sdk/build/features/messages/files
title: Send files
updated_at: 2026-05-25T05:43:43.854Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Send files

Attach files to messages to share information or improve collaboration.

Chat SDK supports multiple file attachments per message (unlike the JavaScript SDK). Each file must be 5 MB or less. Files upload sequentially, so consider implementing a progress indicator for better UX.

:::warning Requires File Sharing
Enable [File Sharing](https://youtu.be/6hnhZ8t1_CU) in the [Admin Portal](https://admin.pubnub.com/) and configure storage region and retention. Align file retention with [Message Persistence](https://www.pubnub.com/docs/chat/kotlin-chat-sdk/build/features/messages/history) retention.
:::

## Send files

Attach files to a [draft message](https://www.pubnub.com/docs/chat/kotlin-chat-sdk/build/features/messages/drafts) and publish using [send()](https://www.pubnub.com/docs/chat/kotlin-chat-sdk/build/features/messages/drafts#send-a-draft-message).

### Method signature

To add files, you must add elements to the `files` field (`MutableList<InputFile>`) of a `MessageDraft` object.

### Sample code

Attach two files of different formats to a text message.

```kotlin
// create a draft message
val messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered = channel.type != ChannelType.PUBLIC)

// add a listener
val listener = { elements: List<MessageElement>, suggestedMentions: PNFuture<List<SuggestedMention>> ->
        updateUI(elements) // updateUI is your own function for updating UI
        suggestedMentions.async { result ->
            result.onSuccess { updateSuggestions(it) } // updateSuggestions is your own function for displaying suggestions
        }
    }
messageDraft.addChangeListener(listener)

// work on editing message with messageDraft.update(text)

// attach files
messageDraft.files.add(
    InputFile("filename.txt", "text/plain", FileInputStream("filename.txt")))
messageDraft.files.add(
    InputFile("document.pdf", "application/pdf", FileInputStream("/path/to/document.pdf")))

messageDraft.send()
```

## Get all message files

`files` returns all files attached to a message.

### Field signature

This field has the following signature:

```kotlin
val files: List<File>
```

### Sample code

List all files attached to the last message on the `support` channel.

```kotlin
val channel: Channel
// ...

// get the last message from the channel’s history
channel.getHistory(count = 1).async { historyResult ->
    historyResult.onSuccess { historyResponse ->
        val lastMessage = historyResponse.messages.firstOrNull()
        if (lastMessage != null) {
            // access the files property of the last message
            val files = lastMessage.files

            if (files.isNotEmpty()) {
                println("The last message contains the following files:")
                files.forEach { file ->
                    println("File Name: ${file.name}, File Type: ${file.type}")
                }
            } else {
                println("The last message does not contain any files.")
            }
        } else {
            println("No messages found in the support channel.")
        }
    }.onFailure {
        println("Error getting history for the support channel: ${it.message}")
        it.printStackTrace()
    }
}
```

## Get all channel files

`getFiles()` returns all files attached to messages on a channel.

### Method signature

This method takes the following parameters:

```kotlin
channel.getFiles(
    limit: Int?,
    next: String? 
): PNFuture<GetFilesResult>
```

#### Input

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| limit | Int | Optional | `100` | Number of files to return. |
| next | String | Optional |  | String token to get the next batch of files. |

#### Output

| Parameter | Description |
| --- | --- |
| `PNFuture<GetFilesResult>`Type: `object` | Returned object containing these fields: `files`, `next`, and `total`. |
| `> files`Type: `Collection<GetFileItem>` | Array containing file details. |
| `>> name`Type: `String` | Name of the file, like `error-1.jpg`. |
| `>> id`Type: `String` | Unique identifier assigned to the file by PubNub, like `736499374`. |
| `>> url`Type: `String` | File's direct downloadable URL. |
| `> next`Type: `String` | Random string returned from the server, indicating a specific position in a data set. Used for forward pagination, it fetches the next page, allowing you to continue from where you left off. |
| `> total`Type: `Int` | Total number of files. |

`GetFileItem` contains the following properties:

| Parameter | Description |
| --- | --- |
| `name`Type: `String` | Name of the file, like `error-1.jpg`. |
| `id`Type: `String` | Unique identifier assigned to the file by PubNub, like `736499374`. |
| `url`Type: `String` | File's direct downloadable URL, like `https://ps.pndsn.com/v1/files/demo/channels/support/files/736499374/error-1.jpg`. |

### Sample code

List all files published on the `support` channel.

```kotlin
val channel: Channel

fun fetchFiles(channel: Channel, next: String?) {
    channel.getFiles(limit = 100, next = next).async { result ->
        result.onSuccess { filesResult ->
            filesResult.files.forEach { file ->
                println("File name: ${file.name}, File URL: ${file.url}")
            }

            // Check if there is another page of results
            if (filesResult.next != null) {
                fetchFiles(channel, filesResult.next)
            }
        }.onFailure {
            // handle error
            println("Error retrieving files: ${it.message}")
        }
    }
}

// ...

fetchFiles(channel, null)
```

## Delete files

`deleteFile()` removes files from PubNub storage.

:::note Endpoint limitation
After deleting a file, you cannot identify which historical messages contained it.
:::

### Method signature

This method takes the following parameters:

```kotlin
channel.deleteFile(
    id: String,
    name: String
): PNFuture<PNDeleteFileResult>
```

#### Input

| Parameter | Description |
| --- | --- |
| `id` *Type: `String`Default: n/a | Unique identifier assigned to the file by PubNub. |
| `name` *Type: `String`Default: n/a | Name of the file. |

#### Output

| Type | Description |
| --- | --- |
| `PNFuture<PNDeleteFileResult>` | Status code of the response. |

### Sample code

Remove a file named `error-screenshot.png` from the `support` channel.

```kotlin
val channel: Channel
// ...

// delete the file named "error-screenshot.png" from the "support" channel
val fileId = "file-id-to-delete" // Replace this with the actual file ID
val fileName = "error-screenshot.png"

channel.deleteFile(fileId, fileName).async { result ->
    result.onSuccess {
        println("File '$fileName' successfully deleted from 'support' channel.")
    }.onFailure {
        // handle error
        println("Error deleting file '$fileName': ${it.message}")
    }
}
```