---
source_url: https://www.pubnub.com/docs/sdks/javascript/api-reference/publish
title: Publish API for JavaScript SDK
updated_at: 2026-11-09T13:29:01.000Z
sdk_name: PubNub JavaScript SDK
sdk_version: 13.1.3
description: "Reference for the PubNub JavaScript SDK publish() and signal() methods: parameters, response, errors, and limits. Covers the deprecated fire() method."
---

# Publish API for JavaScript SDK

PubNub JavaScript SDK, use the latest version: 13.1.3

Install:

```bash
npm install pubnub@13.1.3
```

> For AI agents: documentation index at https://www.pubnub.com/llms-full.txt

The PubNub JavaScript SDK sends a message to one [channel](https://www.pubnub.com/docs/architecture/core-concepts.md#channel) per call with `publish()` and a small payload that PubNub never stores with `signal()`.

Both calls require the publish key of your keyset, which you pass as `publishKey` when you create the client. See [Initialization](https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration.md#initialization).

Each method returns a promise that resolves with the response and rejects with a `PubNubError`. The error carries a `status` object with `category` and `statusCode`, and `status.errorData` holds the details that PubNub returned for a failed request. Each method also takes a callback as the second argument, and with a callback the method returns nothing and PubNub calls it with `(status, response)`. On success, `status.error` is `false` and `status.operation` names the operation, and on failure `status.error` is `true` and `response` is `null`. All examples use `async/await`, so wrap a call in `try...catch` to receive the error status.

For delivery guarantees, ordering, and the difference between messages and signals, see [Publishing messages with PubNub](https://www.pubnub.com/docs/pub-sub/publish/overview.md). For payload shapes and metadata in practice, see [Send different message types](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md). To receive what you publish, see [Subscribe](https://www.pubnub.com/docs/sdks/javascript/api-reference/subscribe.md). To fix a failed publish, see [Troubleshooting](https://www.pubnub.com/docs/sdks/javascript/troubleshooting.md#publishing).

## Publish

`publish()` sends a message to one channel through a PubNub client for JavaScript and reports the timetoken that PubNub assigned to the message. PubNub delivers the message to the clients that subscribe to the channel.

Publish-processing latency, the time PubNub takes to accept and acknowledge a publish request, is about 0.5 ms within the same region.

### Publish: Prerequisites and limitations

* The call rejects with `Missing 'publishKey'` when the client has no `publishKey`.
* A client does not need to subscribe to a channel to publish to it.
* Each call publishes to one channel. To reach several channels, call `publish()` once per channel.
* By default, a PubNub client for JavaScript does not retry a failed publish, so your application owns the retry.

### Publish: Security

PubNub SDKs connect over TLS 1.2 by default, except the Lua SDK and the unsupported Twisted SDK, where you set `ssl` to `true`.

To encrypt the message content, configure `cryptoModule` during initialization. The SDK then encrypts only `message` and sends `channel` and `meta` unencrypted. See [`cryptoModule`](https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration.md#cryptomodule) for the setup and [Data security and encryption](https://www.pubnub.com/docs/security/encryption/overview.md) for background.

### Publish: Message data

A message is the basic unit of data flowing through PubNub, and its payload is any JSON-serializable value. String content in a message payload can include any single-byte or multi-byte UTF-8 character. Pass objects as they are. The SDK serializes `message` and `meta`, so don't call `JSON.stringify()` first. Avoid special classes and functions.

Metadata values must be JSON-serializable. The SDK sends `meta` only when it is an object or an array.

### Publish: Size

PubNub can process messages **up to 2 MB** in size, but the default message payload is limited to 32 KiB. This includes the channel name and any metadata.

The server rejects a larger publish. For the error you see and how to fix it, see [Publish fails with `Message Too Large`](https://www.pubnub.com/docs/sdks/javascript/troubleshooting.md#publish-fails-with-message-too-large). For all publish limits, see [API limits](https://www.pubnub.com/docs/architecture/limits.md#publish). To calculate the payload size, use the [message size calculator](https://www.pubnub.com/docs/pub-sub/publish/send-different-message-types.md#publish-a-message).

### Publish: Publish rate

There is no hard publish rate limit for a keyset in good standing. As a best practice, keep publish rates at 10 to 15 messages per second per channel. Faster rates are possible, but a slow subscriber can fall behind the connection's message buffer.

### Publish: Custom message type

You can optionally provide the `customMessageType` parameter to add your business-specific label or category to the message, for example `text`, `action`, or `poll`.

A custom message type accepted by the PubNub Publish, Signal, and File Sharing APIs must be a case-sensitive alphanumeric string of 3 to 50 characters. Dashes (`-`) and underscores (`_`) are allowed. The value cannot start with a special character or with the reserved prefixes `pn_` or `pn-`.

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| message | any | Yes | n/a | The payload to publish. Any JSON-serializable value, such as an object, array, string, or number. The SDK rejects a falsy value (`0`, `false`, `""`, `null`) with `Missing 'message'`. |
| channel | string | Yes | n/a | The ID of the one channel to publish to. The method takes the ID string, not an [SDK channel entity](https://www.pubnub.com/docs/sdks/javascript/api-reference/subscribe.md#sdk-entities). The SDK rejects an empty value with `Missing 'channel'`. |
| storeInHistory | boolean | Optional | n/a | Whether PubNub stores the message in [Message Persistence](https://www.pubnub.com/docs/data-storage/message-history/overview.md). `true` stores it and `false` skips storage. PubNub stores the message only when Message Persistence is enabled for the keyset. When omitted, the Message Persistence setting of the keyset applies. |
| meta | object or array | Optional | n/a | Metadata that PubNub attaches to the message. Subscribers can use it in [message filters](https://www.pubnub.com/docs/pub-sub/subscribe/filter-received-messages.md). |
| sendByPost | boolean | Optional | `false` | Whether the message travels in the body of an HTTP POST request. `false` puts the message in the URL path of an HTTP GET request. The SDK compresses the body with deflate on Node.js and in browsers that provide `CompressionStream`. |
| ttl | number | Optional | n/a | The number of hours that Message Persistence keeps the message. When omitted, the retention of the keyset applies. PubNub ignores this value when it does not store the message. A value of `0` stores the message with no expiry. A keyset using Unlimited retention ignores any per-message TTL and stores the message indefinitely. |
| customMessageType | string | Optional | n/a | A business-specific label for the message, for example `text`, `action`, or `poll`. The accepted format is in the Custom message type note for this method. |

### Returns

`publish()` resolves with a `PublishResponse`. The `timetoken` is a string, not a number. PubNub assigns every published message a server-side timetoken: a monotonically increasing 17-digit value precise to 100 nanoseconds (10⁻⁷ s), the number of 100-nanosecond intervals since the Unix epoch. For how to use it, see [Publish response and the timetoken](https://www.pubnub.com/docs/pub-sub/publish/overview.md#publish-response-and-the-timetoken).

### Publish errors

`publish()` and `signal()` reject with a `PubNubError`. Read `error.status.category` to tell the cases apart. Validation errors happen before the SDK sends any request.

| Condition | Result |
| --- | --- |
| `message` is `0`, `false`, `""`, `null`, or omitted | `PNValidationErrorCategory`. The `status.message` value is `Missing 'message'`. |
| `channel` is omitted or empty | `PNValidationErrorCategory`. The `status.message` value is `Missing 'channel'`. |
| `publishKey` was not set at initialization | `PNValidationErrorCategory`. The `status.message` value is `Missing 'publishKey'`. |
| `customMessageType` is not in the accepted format | The SDK does not check the format, so PubNub rejects the request. Read `status.category` and `status.errorData` for the reason. |
| The token or `authKey` has no write permission on the channel | `PNAccessDeniedCategory` with HTTP 403. See [Access Manager](https://www.pubnub.com/docs/security/access-control/overview.md). |
| The network is unreachable | `PNNetworkIssuesCategory` with `status.statusCode` `0`. |
| `message` contains a circular reference | No `PubNubError`. The call rejects with a plain `TypeError`, `error.status` is `undefined`, and a callback is not called. |

### Examples for Publish

#### Syntax

```typescript
pubnub.publish({
    message: any,
    channel: string,
    meta?: object | Array<any>,
    storeInHistory?: boolean,
    sendByPost?: boolean,
    ttl?: number,
    customMessageType?: string
}): Promise<PublishResponse>;
```

#### Basic usage

Publish a message with only the required parameters.

```javascript
import PubNub from 'pubnub';
// Initialize PubNub with your keys
const pubnub = new PubNub({
  publishKey: 'YOUR_PUBLISH_KEY',
  subscribeKey: 'YOUR_SUBSCRIBE_KEY',
  userId: 'YOUR_USER_ID',
});
```

```javascript
const { timetoken } = await pubnub.publish({
  channel: 'my_channel',
  message: { text: 'Hello' },
});

console.log(timetoken); // "17918851187695440" (a string)
```

#### Returns

```typescript
type PublishResponse = {
    timetoken: string
}
```

```json
{ "timetoken": "17918851187695440" }
```

#### Publish with optional parameters

```javascript
const response = await pubnub.publish({
  message: { text: 'Hello World' },
  channel: 'my_channel',
  sendByPost: false,
  storeInHistory: true,
  meta: { sender: 'user123' },
  customMessageType: 'text-message',
});
console.log('Publish Success:', response);
```

#### Store the message for 10 hours

```javascript
const response = await pubnub.publish({
  message: 'hello!',
  channel: 'my_channel',
  storeInHistory: true,
  ttl: 10,
  customMessageType: 'text-message',
});

console.log('message published with server response:', response);
```

#### Publish a falsy value

Wrap the value in an object, because `0`, `false`, `""`, and `null` fail validation.

```javascript
// message: 0 is rejected with "Missing 'message'", so wrap the value
await pubnub.publish({
  channel: 'my_channel',
  message: { value: 0 },
});
```

#### Publish errors

```javascript
try {
  await pubnub.publish({
    channel: 'my_channel',
    message: { text: 'Hello' },
  });
} catch (e) {
  const status = (e as PubNubError).status;

  if (status?.category === 'PNValidationErrorCategory') {
    console.error('The call is invalid:', status.message);
  } else if (status?.category === 'PNAccessDeniedCategory') {
    console.error('403: the token or authKey has no write permission on the channel');
  } else if (status?.category === 'PNNetworkIssuesCategory') {
    console.error('The network is unreachable. Retry the publish yourself.');
  } else {
    console.error(status?.category, status?.statusCode, status?.errorData);
  }
}
```

## Signal

`signal()` sends a signal to the clients that subscribe to one channel, using a PubNub client for JavaScript.

PubNub never stores signals in Message Persistence, regardless of keyset settings. Signal payloads are limited to 64 bytes. A signal cannot trigger mobile push notifications. A signal does not support `meta`, `storeInHistory`, `ttl`, or `sendByPost`. The SDK does not encrypt the `message` of a signal, even when a `cryptoModule` is configured.

PubNub rejects a payload over the limit. Read `status.category` and `status.errorData` for the reason.

`signal()` fails validation on the same inputs as `publish()`: a missing or falsy `message`, a missing `channel`, or a missing `publishKey`. See [Publish errors](#publish-errors).

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| message | any | Yes | n/a | The payload to send. Any JSON-serializable value. The SDK rejects a falsy value with `Missing 'message'`. |
| channel | string | Yes | n/a | The ID of the one channel to send the signal to. The method takes the ID string, not an [SDK channel entity](https://www.pubnub.com/docs/sdks/javascript/api-reference/subscribe.md#sdk-entities). The SDK rejects an empty value with `Missing 'channel'`. |
| customMessageType | string | Optional | n/a | A business-specific label for the signal, for example `text`, `action`, or `poll`. The accepted format is the same as for `publish()`. See [the Custom message type note under Publish](#publish). |

### Returns

`signal()` resolves with a `SignalResponse`. The `timetoken` is a string.

### Examples for Signal

#### Syntax

```typescript
pubnub.signal({
    message: any,
    channel: string,
    customMessageType?: string
}): Promise<SignalResponse>;
```

#### Signal a message to a channel

```javascript
const response = await pubnub.signal({
  message: 'hello',
  channel: 'foo',
  customMessageType: 'text-message',
});
console.log('signal response:', response);
```

#### Returns

```typescript
type SignalResponse = {
    timetoken: string
}
```

## Deprecated publish methods

`fire()` is a deprecated method of the PubNub JavaScript SDK that sends a message to Functions event handlers and Illuminate, and `publish()` replaces it.

The reference for apps that still call `fire()` is [Publish API: deprecated fire() method for JavaScript SDK](https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-legacy.md). New apps use [`publish()`](#publish) with `storeInHistory: false` and `replicate: false`.

Last updated at: 2026-11-09T13:29:01.000Z
