---
source_url: https://www.pubnub.com/docs/data-storage/files/send-file-to-channel
title: Send a file to a channel
updated_at: 2026-09-30T07:20:08.000Z
---

# Send a file to a channel

## Documentation index

To discover more PubNub resources:

1. Fetch [PubNub's llms.txt](https://www.pubnub.com/llms-full.txt) for a list of available pages in Markdown format.
2. Identify relevant URLs from that index.
3. Fetch the target pages.

Do not assume a path exists, always check the index first.

This guide shows you how to upload a file to a PubNub channel. When the upload completes, PubNub delivers a file event to all subscribers on that channel.

The examples on this page are written for the current SDK releases: C# 9.0.0, Dart 8.0.3, Go v10.0.0, Java 6.4.5, JavaScript 13.0.3 (web, Node.js, and React Native tabs), Objective-C 7.0.4, PHP 9.0.3, Python 10.7.2, and Swift 10.2.0. Each example assumes a PubNub client initialized for its SDK, unless the example sets one up itself.

**Prerequisite:** File Sharing must be enabled on your keyset in the [Admin Portal](https://admin.pubnub.com). For how the feature works, see [Files](https://www.pubnub.com/docs/data-storage/files/overview.md).

## File size limit

| Function | Limit | Notes |
| --- | --- | --- |
| File size | 5 MB | To raise it, contact [support@pubnub.com](mailto:support@pubnub.com). |
| File retention | File retention is 1 or 7 days on the Free plan, 30 days on Starter, and Unlimited on Pro. | Set it per keyset in the [Admin Portal](https://admin.pubnub.com/). |
| Files per list call | A single list-files call returns up to 100 files for a channel. |  |

## Send a file

Choose the channel and the file. You can attach an optional text caption to the upload.

:::note Custom message types
Not all SDKs support sending files with a custom message type. For details, see [Message Types](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md).
:::

### JavaScript

The upload code differs by environment because each one selects or reads the file differently. Choose the tab for your environment.

#### Web

```javascript
import PubNub from 'pubnub';

const pubnub = new PubNub({
  publishKey: 'YOUR_PUBLISH_KEY',
  subscribeKey: 'YOUR_SUBSCRIBE_KEY',
  userId: 'YOUR_USER_ID',
});

const input = document.querySelector('input[type="file"]');

input.addEventListener('change', async () => {
  const file = input.files[0];
  if (!file) {
    console.error('No file selected.');
    return;
  }

  const result = await pubnub.sendFile({
    channel: 'my_channel',
    file: file,
    customMessageType: 'file-message',
  });
});
```

#### Node.js

```javascript
import fs from 'fs';
import PubNub from 'pubnub';

const pubnub = new PubNub({
  publishKey: 'YOUR_PUBLISH_KEY',
  subscribeKey: 'YOUR_SUBSCRIBE_KEY',
  userId: 'YOUR_USER_ID',
});

const myFile = fs.createReadStream('./cat_picture.jpg');

const result = await pubnub.sendFile({
  channel: 'my_channel',
  file: { stream: myFile, name: 'cat_picture.jpg', mimeType: 'image/jpeg' },
  customMessageType: 'file-message',
});
```

#### React Native

```javascript
import PubNub from 'pubnub';

const pubnub = new PubNub({
  publishKey: 'YOUR_PUBLISH_KEY',
  subscribeKey: 'YOUR_SUBSCRIBE_KEY',
  userId: 'YOUR_USER_ID',
});

// Local URI of the image to upload, for example returned by an image picker.
const imageUri = 'file:///path/to/cat_picture.jpg';

const result = await pubnub.sendFile({
  channel: 'my_channel',
  message: {
    test: 'message',
    value: 42,
  },
  file: {
    uri: imageUri,
    name: 'cat_picture.jpg',
    mimeType: 'image/jpeg',
  },
  customMessageType: 'file-message',
});
```

### C#

```csharp
PNResult<PNFileUploadResult> fileUploadResponse = await pubnub.SendFile()
    .Channel("my_channel")
    .File("cat_picture.jpg") // checks the bin folder if no path is provided
    .Message("Look at this photo!")
    .ExecuteAsync();
PNFileUploadResult fileUploadResult = fileUploadResponse.Result;
PNStatus fileUploadStatus = fileUploadResponse.Status; // contains troubleshooting info
if (!fileUploadStatus.Error && fileUploadResult != null) // checks if successful
{
    Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(fileUploadResult));
}
else
{
    Console.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(fileUploadStatus));
}
```

### Go

```go
file, err := os.Open("cat_picture.jpg")
defer file.Close()
if err != nil {
    panic(err)
}
resSendFile, statusSendFile, errSendFile := pn.SendFile().
  Channel("my_channel").
  Message("Look at this photo!").
  Name("cat_picture.jpg").
  File(file).Execute()
fmt.Println(resSendFile, statusSendFile, errSendFile)
fmt.Println(resSendFile.Data.ID)
```

### Objective-C

```objectivec
NSURL *localFileURL = ...;
PNSendFileRequest *request = [PNSendFileRequest requestWithChannel:@"my_channel"
                                                           fileURL:localFileURL];
request.customMessageType = @"file-message";

[self.client sendFileWithRequest:request completion:^(PNSendFileStatus *status) {
    if (!status.isError) {
        /**
         * File upload successfully completed.
         * Uploaded file information is available here:
         *   status.data.fileIdentifier is the unique file identifier
         *   status.data.fileName is the name used to store the file
         */
    } else {
        /**
         * Handle send file error. Check the 'category' property for reasons
         * why the request may have failed.
         *
         * Check 'status.data.fileUploaded' to determine whether to resend the
         * request or if only file message publish should be called.
         */
    }
}];
```

### Java

```java
pubnub.sendFile()
    .channel("my_channel")
    .fileName("cat_picture.jpg")
    .customMessageType("file-message")
    .inputStream(inputStream)
    .message("Look at this photo!")
    .async(result -> {
        result.onSuccess(res -> {
                System.out.println("send timetoken: " + res.getTimetoken());
                System.out.println("send status: " + res.getStatus());
                System.out.println("send fileId: " + res.getFile().getId());
                System.out.println("send fileName: " + res.getFile().getName());
        }).onFailure(exception -> {
            exception.printStackTrace();
        });
    });
```

### Python

```python
# synchronous
with open("cat_picture.jpg", "rb") as fd:
    envelope = pubnub.send_file() \
        .channel("my_channel") \
        .file_name("cat_picture.jpg") \
        .message({"test_message": "test"}) \
        .custom_message_type('file-message') \
        .should_store(True) \
        .ttl(222) \
        .file_object(fd) \
        .cipher_key("secret") \
        .sync()

# multithreaded asynchronous
def callback(result, status):
    if status.is_error():
        print(f"Request failed: {status.error_data}")
        return
    print(result)

with open("cat_picture.jpg", "rb") as fd:
    pubnub.send_file() \
        .channel("my_channel") \
        .file_name("cat_picture.jpg") \
        .message({"test_message": "test"}) \
        .custom_message_type('file-message') \
        .should_store(True) \
        .ttl(222) \
        .file_object(fd.read()) \
        .cipher_key("secret") \
        .pn_async(callback)
```

### PHP

```php
$channelName = "file-channel";
$testFileName = "pn.gif";

$config = new PNConfiguration();
$config->setSubscribeKey(getenv('SUBSCRIBE_KEY', 'demo'));
$config->setPublishKey(getenv('PUBLISH_KEY', 'demo'));
$config->setUserId('example');

$pubnub = new PubNub($config);
$fileHandle = fopen(__DIR__ . DIRECTORY_SEPARATOR . $testFileName, "r");
$sendFileResult = $pubnub->sendFile()
    ->channel($channelName)
    ->fileName($testFileName)
    ->message("Hello from PHP SDK")
    ->fileHandle($fileHandle)
    ->sync();
fclose($fileHandle);
$fileId = $sendFileResult->getFileId();
$fileName = $sendFileResult->getFileName();

print("File uploaded successfully: {$fileName} with ID: {$fileId}\n");
```

### Swift

```swift
pubnub.send(
  .file(url: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("cat_picture.jpg")),
  channel: "my_channel",
  remoteFilename: "cat_picture.jpg",
  publishRequest: .init(additionalMessage: ["text": "Look at this photo!"], customMessageType: "file-message")
) { (fileTask) in
  print("The task \(fileTask.urlSessionTask.taskIdentifier) has started uploading; no need to call `resume()`")
  print("If needed, the `URLSessionUploadTask` can be accessed with `fileTask.urlSessionTask`")
  print("You can use `fileTask.progress` to populate a  `UIProgressView`/`ProgressView` ")
} completion: { (result) in
  switch result {
  case let .success((task, file, publishedAt)):
    print("The file with an ID of \(file.fileId) was uploaded at \(publishedAt) timetoken) ")
  case let .failure(error):
    print("An error occurred while uploading the file: \(error.localizedDescription)")
  }
}
```

### Dart

```dart
import 'dart:io';
import 'package:pubnub/pubnub.dart';

void main() async {
  var pubnub = PubNub(
    defaultKeyset: Keyset(
      subscribeKey: 'sub-c-abc-123',  // Replace with your subscribe key
      publishKey: 'pub-c-def-456'     // Replace with your publish key
    ),
  );

  var inputFile = File('cat_picture.jpg').readAsBytesSync();

  try {
    var result = await pubnub.files.sendFile(
      'my_channel',
      'cat_picture.jpg',
      inputFile,
      fileMessage: 'Look at this photo!',
      customMessageType: 'file-message'   // Example with custom message type
    );

    print('File uploaded - timetoken ${result.timetoken}');
  } catch (e) {
    print('Failed to send file: $e');
  }
}
```

A successful upload returns a timetoken. Subscribers on the channel receive a file event carrying the file ID, file name, and a download URL. For how to handle that event on the subscriber side, see [Receive and download files](https://www.pubnub.com/docs/data-storage/files/receive-and-download-files.md).

## Encrypt a file

To encrypt a file before upload, set a cipher key in the SDK client configuration or pass it per upload request. Any client that downloads the file must use the same key. For how encryption works, see [Files](https://www.pubnub.com/docs/data-storage/files/overview.md#encryption).

The Python example above shows `cipher_key("secret")` as an inline parameter. Check your SDK's configuration reference for the client-level cipher key option.

## Related tasks

* [Receive and download files](https://www.pubnub.com/docs/data-storage/files/receive-and-download-files.md). Handle the file event on the subscriber side and build a download URL.
* [List and manage stored files](https://www.pubnub.com/docs/data-storage/files/list-and-manage-stored-files.md). List files in a channel and delete uploads.

Last updated at: 2026-09-30T07:20:08.000Z
