---
source_url: https://www.pubnub.com/docs/sdks/go/api-reference/configuration
title: Configuration API for Go SDK
updated_at: 2026-06-04T11:11:45.676Z
sdk_name: PubNub Go SDK
sdk_version: 8.2.0
---

> 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


# Configuration API for Go SDK

PubNub Go SDK, use the latest version: 8.2.0

Install:

```bash
go get github.com/pubnub/go/v8@8.2.0
```

Go complete API reference for building real-time applications on PubNub, including basic usage and sample code. [View on GoDoc](https://godoc.org/github.com/pubnub/go)

## Configuration

`pubnub.Config` stores settings that control the PubNub client. The configuration exposes properties to precisely configure client behavior.

### Method(s)

Create a configuration instance with:

```go
config := pubnub.NewConfigWithUserId(UserId)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| SubscribeKey | string | Yes |  | Subscribe key from the Admin Portal. |
| PublishKey | string | Optional | `None` | Publish key from the Admin Portal (required if publishing). |
| SecretKey | string | Optional | `None` | Secret key (only required for modifying or revealing access permissions). |
| SetUserId | UserId | Yes |  | `userId` to use. The `UserId` object takes `String` as an argument. You should set a unique identifier for the user or the device that connects to PubNub. It's a UTF-8 encoded string of up to 92 alphanumeric characters. If you don't set the `userId`, you won't be able to connect to PubNub. |
| AuthKey | string | Optional | `None` | If Access Manager is utilized, the client uses this `AuthKey` in all restricted requests. |
| Secure | bool | Optional | `True` | Use `SSL`. |
| MessageQueueOverflowCount | int | Optional | `100` | Fires `PNRequestMessageCountExceededCategory` when a single subscribe response contains more than this many messages. |
| ConnectTimeout | int | Optional | `10` | Maximum time to establish a connection, in seconds. |
| SubscribeRequestTimeout | int | Optional | `310` | Subscribe request timeout, in seconds. |
| NonSubscribeRequestTimeout | int | Optional | `10` | Non-subscribe request timeout, in seconds. |
| FilterExpression | string | Optional | `None` | Feature to subscribe with a custom filter expression. |
| Origin | string | Optional | `ps.pndsn.com` | Custom origin if needed. To request a custom domain, contact support and follow the [request process](https://www.pubnub.com/docs/general/setup/data-security#request-process). |
| MaximumReconnectionRetries | int | Optional | `50` | The config sets how many times to retry to reconnect before giving up. |
| SetPresenceTimeout | int | Optional | `0` | How long the server considers the client alive for presence. The client sends periodic heartbeats to stay active. If no heartbeat arrives within the timeout, the client is marked inactive and a "timeout" event is emitted on the [presence channel](https://www.pubnub.com/docs/general/presence/overview). |
| SetPresenceTimeoutWithCustomInterval | int | Optional | `0` | How often the client sends heartbeats. For shorter presence timeouts, set roughly to `(SetPresenceTimeout / 2) - 1`. |
| SuppressLeaveEvents | bool | Optional |  | When `true` the SDK doesn't send out the `leave` requests. |
| MaxIdleConnsPerHost | int | Optional | `30` | Used to set the value of HTTP Transport's MaxIdleConnsPerHost. |
| FileMessagePublishRetryLimit | int | Optional | `5` | The number of tries made in case of Publish File Message failure. |
| CryptoModule | crypto.NewAesCbcCryptor(CipherKey, | Optional | `None` | The cryptography module used for encryption and decryption of messages and files. Takes the `CipherKey` and `UseRandomInitializationVector` parameters as arguments. For more information, refer to the [CryptoModule](#cryptomodule) section. |
| CipherKey | string | Optional | `None` | This way of setting this parameter is deprecated, pass it to `CryptoModule` instead. If CipherKey is passed, all communications to/from PubNub will be encrypted. |
| UseRandomInitializationVector | bool | Optional | `true` | This way of setting this parameter is deprecated, pass it to `CryptoModule` instead. When true the initialization vector (IV) is random for all requests (not just for file upload). When false the IV is hard-coded for all requests except for file upload. |
| UUID | string | Yes |  | This parameter is deprecated, use `userId` instead. UUID to use. You should set a unique UUID to identify the user or the device that connects to PubNub. If you don't set the UUID, you won't be able to connect to PubNub. |

:::warning Disabling random initialization vector
Disable random initialization vector (IV) only for backward compatibility (<`5.0.0`) with existing applications. Never disable random IV on new applications.
:::

#### CryptoModule

`CryptoModule` encrypts and decrypts messages and files. From 7.1.2, you can configure the algorithms it uses.

Each SDK includes two options: legacy 128‑bit encryption and recommended 256‑bit AES‑CBC. For background, see [Message Encryption](https://www.pubnub.com/docs/general/setup/data-security#message-encryption) and [File Encryption](https://www.pubnub.com/docs/general/setup/data-security#file-encryption).

If you don't set `CryptoModule` but set `cipherKey` and `useRandomInitializationVector` in config, the client uses legacy encryption.

For configuration details, utilities, and examples, see [Encryption](https://www.pubnub.com/docs/sdks/go/api-reference/encryption).

:::note Legacy encryption with 128-bit cipher key entropy
You don't have to change your encryption configuration if you want to keep using the legacy encryption. If you want to use the recommended 256 bit AES-CBC encryption, you must explicitly set that in PubNub config.
:::

### Sample code

:::tip Reference code
This example is a self-contained code snippet ready to be run. It includes necessary imports and executes methods with console logging. Use it as a reference when working with other examples in this document.
:::

:::note Required User ID
Always set the `UserId` to uniquely identify the user or device that connects to PubNub. This `UserId` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UserId`, you won't be able to connect to PubNub.
:::

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_initBasic demonstrates basic PubNub initialization
func Example_initBasic() {
	// Create configuration with a unique user ID
	config := pubnub.NewConfigWithUserId(pubnub.UserId("my-user-id"))

	// Set your PubNub keys
	config.SubscribeKey = "demo" // Replace with your subscribe key
	config.PublishKey = "demo"   // Replace with your publish key

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Initialize PubNub client
	pn := pubnub.NewPubNub(config)

	if pn != nil {
		fmt.Println("PubNub client initialized successfully")
	}

	// Output:
	// PubNub client initialized successfully
}
```

### Server response

Configured and ready to use client configuration instance.

### Other examples

#### Configure request timeouts

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setTimeouts demonstrates configuring request timeouts
func Example_setTimeouts() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set custom timeouts (in seconds)
	config.ConnectTimeout = 15             // Connection timeout
	config.NonSubscribeRequestTimeout = 20 // Timeout for publish, history, etc.
	config.SubscribeRequestTimeout = 300   // Timeout for long-poll subscribe
	config.FileUploadRequestTimeout = 120  // Timeout for file uploads

	pn := pubnub.NewPubNub(config)

	if pn != nil {
		fmt.Println("Timeouts configured successfully")
	}

	// Output:
	// Timeouts configured successfully
}
```

#### Configure presence timeout

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setPresenceTimeout demonstrates configuring presence timeout
func Example_setPresenceTimeout() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set presence timeout (how long before user appears offline)
	// The heartbeat interval is automatically calculated
	config.SetPresenceTimeout(60) // 60 seconds

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.PresenceTimeout == 60 {
		fmt.Println("Presence timeout configured to 60 seconds")
	}

	// Output:
	// Presence timeout configured to 60 seconds
}
```

#### Configure presence timeout with custom interval

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setPresenceCustomInterval demonstrates custom presence timeout and interval
func Example_setPresenceCustomInterval() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set custom presence timeout and heartbeat interval
	config.SetPresenceTimeoutWithCustomInterval(120, 55) // timeout: 120s, interval: 55s

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.PresenceTimeout == 120 {
		fmt.Println("Custom presence configuration set")
	}

	// Output:
	// Custom presence configuration set
}
```

#### Enable secure connection

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_enableSecureConnection demonstrates enabling TLS/SSL
func Example_enableSecureConnection() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Enable secure connection (TLS/SSL) - enabled by default
	config.Secure = true

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.Secure {
		fmt.Println("Secure connection enabled")
	}

	// Output:
	// Secure connection enabled
}
```

#### Configure reconnection policy

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setReconnectionPolicy demonstrates configuring reconnection behavior
func Example_setReconnectionPolicy() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set reconnection policy
	// Options: PNNonePolicy, PNLinearPolicy, PNExponentialPolicy
	config.PNReconnectionPolicy = pubnub.PNLinearPolicy
	config.MaximumReconnectionRetries = 10 // Maximum reconnection attempts

	pn := pubnub.NewPubNub(config)

	if pn != nil {
		fmt.Println("Reconnection policy configured")
	}

	// Output:
	// Reconnection policy configured
}
```

#### Enable SDK logging

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"
	"log"
	"io"
	"os"

	pubnub "github.com/pubnub/go/v8"
)

// Example_enableLogging demonstrates enabling SDK logging
func Example_enableLogging() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Enable logging to stdout
	config.Log = log.New(os.Stdout, "PubNub: ", log.Ldate|log.Ltime|log.Lshortfile)

	// snippet.hide
	// For testing, override with discard logger to avoid test output
	config.Log = log.New(io.Discard, "PubNub: ", log.Ldate|log.Ltime|log.Lshortfile)
	// snippet.show

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.Log != nil {
		fmt.Println("Logging enabled")
	}

	// Output:
	// Logging enabled
}
```

#### Set custom origin

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setOrigin demonstrates setting a custom origin
func Example_setOrigin() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set custom origin (default is "ps.pndsn.com")
	config.Origin = "ps.pndsn.com"

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.Origin != "" {
		fmt.Println("Custom origin configured")
	}

	// Output:
	// Custom origin configured
}
```

#### Suppress leave events

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_suppressLeaveEvents demonstrates suppressing leave events
func Example_suppressLeaveEvents() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Suppress leave events when unsubscribing
	config.SuppressLeaveEvents = true

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.SuppressLeaveEvents {
		fmt.Println("Leave events suppressed")
	}

	// Output:
	// Leave events suppressed
}
```

#### Configure maximum concurrent workers

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setMaxWorkers demonstrates configuring maximum concurrent workers
func Example_setMaxWorkers() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set maximum number of workers for concurrent requests
	config.MaxWorkers = 50 // Default is 20

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.MaxWorkers == 50 {
		fmt.Println("Max workers configured to 50")
	}

	// Output:
	// Max workers configured to 50
}
```

### Proxy configuration

The following sample configures a client to use a proxy for subscribe requests:

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"

	pubnub "github.com/pubnub/go/v8"
)

// proxySubscribe demonstrates configuring a proxy for subscribe requests
func proxySubscribe() {
	// Configure a proxy specifically for subscribe requests.
	var pn *pubnub.PubNub
	config := pubnub.NewConfigWithUserId(pubnub.UserId("myUniqueUserId"))
	config.UseHTTP2 = false

	pn = pubnub.NewPubNub(config)

	transport := &http.Transport{
		MaxIdleConnsPerHost: pn.Config.MaxIdleConnsPerHost,
		Dial: (&net.Dialer{
			Timeout:   time.Duration(pn.Config.ConnectTimeout) * time.Second,
			KeepAlive: 30 * time.Minute,
		}).Dial,
		ResponseHeaderTimeout: time.Duration(pn.Config.SubscribeRequestTimeout) * time.Second,
	}
	proxyURL, err := url.Parse(fmt.Sprintf("http://%s:%s@%s:%d", "proxyUser", "proxyPassword", "proxyServer", 8080))

	if err == nil {
		transport.Proxy = http.ProxyURL(proxyURL)
	} else {
		fmt.Printf("ERROR: creatSubHTTPClient: Proxy connection error: %s", err.Error())
	}
	c := pn.GetSubscribeClient()
	c.Transport = transport
	pn.SetSubscribeClient(c)
}
```

The following sample configures a client to use a proxy for *non-subscribe* requests:

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"

	pubnub "github.com/pubnub/go/v8"
)

// proxyNonSubscribe demonstrates configuring a proxy for non-subscribe requests
func proxyNonSubscribe() {
	// Configure a proxy for non-subscribe requests (publish, history, etc.).
	var pn *pubnub.PubNub
	config := pubnub.NewConfigWithUserId(pubnub.UserId("myUniqueUserId"))
	config.UseHTTP2 = false

	pn = pubnub.NewPubNub(config)

	transport := &http.Transport{
		MaxIdleConnsPerHost: pn.Config.MaxIdleConnsPerHost,
		Dial: (&net.Dialer{
			Timeout:   time.Duration(pn.Config.ConnectTimeout) * time.Second,
			KeepAlive: 30 * time.Minute,
		}).Dial,
		ResponseHeaderTimeout: time.Duration(pn.Config.NonSubscribeRequestTimeout) * time.Second,
	}
	proxyURL, err := url.Parse(fmt.Sprintf("http://%s:%s@%s:%d", "proxyUser", "proxyPassword", "proxyServer", 8080))

	if err == nil {
		transport.Proxy = http.ProxyURL(proxyURL)
	} else {
		fmt.Printf("ERROR: createNonSubHTTPClient: Proxy connection error: %s", err.Error())
	}
	c := pn.GetClient()
	c.Transport = transport
	pn.SetClient(c)
}
```

## Initialization

Add PubNub to your project using one of the procedures defined in the [Getting Started guide](https://www.pubnub.com/docs/sdks/go).

### Description

Initialize the PubNub Client Application Programming Interface (API) context before calling any API. This sets account-level credentials such as `PublishKey` and `SubscribeKey`.

### Method(s)

Initialize PubNub with:

```go
pn := pubnub.NewPubNub(config)
```

| Parameter | Description |
| --- | --- |
| `config` *Type: Config | Goto [Configuration](#configuration) for more details. |

### Sample code

#### Initialize the PubNub client API

:::note Required User ID
Always set the `UserId` to uniquely identify the user or device that connects to PubNub. This `UserId` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UserId`, you won't be able to connect to PubNub.
:::

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_initBasic demonstrates basic PubNub initialization
func Example_initBasic() {
	// Create configuration with a unique user ID
	config := pubnub.NewConfigWithUserId(pubnub.UserId("my-user-id"))

	// Set your PubNub keys
	config.SubscribeKey = "demo" // Replace with your subscribe key
	config.PublishKey = "demo"   // Replace with your publish key

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Initialize PubNub client
	pn := pubnub.NewPubNub(config)

	if pn != nil {
		fmt.Println("PubNub client initialized successfully")
	}

	// Output:
	// PubNub client initialized successfully
}
```

### Returns

Returns the `PubNub` instance to call APIs such as `Publish()`, `Subscribe()`, `History()`, and `HereNow()`.

### Other examples

#### Initialization for a read-only client

In the case where a client will only read messages and never publish to a channel, you can simply omit the `PublishKey` when initializing the client:

:::note Required User ID
Always set the `UserId` to uniquely identify the user or device that connects to PubNub. This `UserId` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UserId`, you won't be able to connect to PubNub.
:::

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_initReadOnly demonstrates read only PubNub initialization
func Example_initReadOnly() {
	// Create configuration with a unique user ID
	config := pubnub.NewConfigWithUserId(pubnub.UserId("my-user-id"))

	// Set your PubNub keys
	config.SubscribeKey = "demo" // Replace with your subscribe key

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Initialize PubNub client
	pn := pubnub.NewPubNub(config)

	if pn != nil {
		fmt.Println("PubNub client initialized successfully")
	}

	// Output:
	// PubNub client initialized successfully
}
```

#### Initialize with generated UUID

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_initWithUUID demonstrates initialization with a generated UUID
func Example_initWithUUID() {
	// Generate a unique UUID for the user
	uuid := pubnub.GenerateUUID()

	// Create configuration with the generated UUID
	config := pubnub.NewConfigWithUserId(pubnub.UserId(uuid))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.GetUserId() != "" {
		fmt.Println("PubNub initialized with generated UUID")
	}

	// Output:
	// PubNub initialized with generated UUID
}
```

## Event listeners

You can receive connectivity status, messages, and presence notifications via listeners.

Add listeners before calling the method.

#### Add listeners

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// addListeners demonstrates adding event listeners
func addListeners() {
	listener := pubnub.NewListener()

	go func() {
		for {
			select {
			case signal := <-listener.Signal:
				//Channel
				fmt.Println(signal.Channel)
				//Subscription
				fmt.Println(signal.Subscription)
				//Payload
				fmt.Println(signal.Message)
				//Publisher ID
				fmt.Println(signal.Publisher)
				//Timetoken
				fmt.Println(signal.Timetoken)
			case status := <-listener.Status:
				switch status.Category {
				case pubnub.PNDisconnectedCategory:
					// this is the expected category for an unsubscribe. This means there
					// was no error in unsubscribing from everything
				case pubnub.PNConnectedCategory:
					// this is expected for a subscribe, this means there is no error or issue whatsoever
				case pubnub.PNReconnectedCategory:
					// this usually occurs if subscribe temporarily fails but reconnects. This means
					// there was an error but there is no longer any issue
				case pubnub.PNAccessDeniedCategory:
					// this means that Access Manager does allow this client to subscribe to this
					// channel and channel group configuration. This is another explicit error
				}
			case message := <-listener.Message:
				//Channel
				fmt.Println(message.Channel)
				//Subscription
				fmt.Println(message.Subscription)
				//Payload
				fmt.Println(message.Message)
				//Publisher ID
				fmt.Println(message.Publisher)
				//Timetoken
				fmt.Println(message.Timetoken)
			case presence := <-listener.Presence:
				fmt.Println(presence.Event)
				//Channel
				fmt.Println(presence.Channel)
				//Subscription
				fmt.Println(presence.Subscription)
				//Timetoken
				fmt.Println(presence.Timetoken)
				//Occupancy
				fmt.Println(presence.Occupancy)
			case uuidEvent := <-listener.UUIDEvent:
				fmt.Printf("uuidEvent.Channel: %s\n", uuidEvent.Channel)
				fmt.Printf("uuidEvent.SubscribedChannel: %s\n", uuidEvent.SubscribedChannel)
				fmt.Printf("uuidEvent.Event: %s\n", uuidEvent.Event)
				fmt.Printf("uuidEvent.UUID: %s\n", uuidEvent.UUID)
				fmt.Printf("uuidEvent.Description: %s\n", uuidEvent.Description)
				fmt.Printf("uuidEvent.Timestamp: %s\n", uuidEvent.Timestamp)
				fmt.Printf("uuidEvent.Name: %s\n", uuidEvent.Name)
				fmt.Printf("uuidEvent.ExternalID: %s\n", uuidEvent.ExternalID)
				fmt.Printf("uuidEvent.ProfileURL: %s\n", uuidEvent.ProfileURL)
				fmt.Printf("uuidEvent.Email: %s\n", uuidEvent.Email)
				fmt.Printf("uuidEvent.Updated: %s\n", uuidEvent.Updated)
				fmt.Printf("uuidEvent.ETag: %s\n", uuidEvent.ETag)
				fmt.Printf("uuidEvent.Custom: %v\n", uuidEvent.Custom)
			case channelEvent := <-listener.ChannelEvent:
				fmt.Printf("channelEvent.Channel: %s\n", channelEvent.Channel)
				fmt.Printf("channelEvent.SubscribedChannel: %s\n", channelEvent.SubscribedChannel)
				fmt.Printf("channelEvent.Event: %s\n", channelEvent.Event)
				fmt.Printf("channelEvent.Channel: %s\n", channelEvent.Channel)
				fmt.Printf("channelEvent.Description: %s\n", channelEvent.Description)
				fmt.Printf("channelEvent.Timestamp: %s\n", channelEvent.Timestamp)
				fmt.Printf("channelEvent.Updated: %s\n", channelEvent.Updated)
				fmt.Printf("channelEvent.ETag: %s\n", channelEvent.ETag)
				fmt.Printf("channelEvent.Custom: %v\n", channelEvent.Custom)
			case membershipEvent := <-listener.MembershipEvent:
				fmt.Printf("membershipEvent.Channel: %s\n", membershipEvent.Channel)
				fmt.Printf("membershipEvent.SubscribedChannel: %s\n", membershipEvent.SubscribedChannel)
				fmt.Printf("membershipEvent.Event: %s\n", membershipEvent.Event)
				fmt.Printf("membershipEvent.Channel: %s\n", membershipEvent.Channel)
				fmt.Printf("membershipEvent.UUID: %s\n", membershipEvent.UUID)
				fmt.Printf("membershipEvent.Description: %s\n", membershipEvent.Description)
				fmt.Printf("membershipEvent.Timestamp: %s\n", membershipEvent.Timestamp)
				fmt.Printf("membershipEvent.Custom: %v\n", membershipEvent.Custom)
			case messageActionsEvent := <-listener.MessageActionsEvent:
				fmt.Printf("messageActionsEvent.Channel: %s\n", messageActionsEvent.Channel)
				fmt.Printf("messageActionsEvent.SubscribedChannel: %s\n", messageActionsEvent.SubscribedChannel)
				fmt.Printf("messageActionsEvent.Event: %s\n", messageActionsEvent.Event)
				fmt.Printf("messageActionsEvent.Data.ActionType: %s\n", messageActionsEvent.Data.ActionType)
				fmt.Printf("messageActionsEvent.Data.ActionValue: %s\n", messageActionsEvent.Data.ActionValue)
				fmt.Printf("messageActionsEvent.Data.ActionTimetoken: %s\n", messageActionsEvent.Data.ActionTimetoken)
				fmt.Printf("messageActionsEvent.Data.MessageTimetoken: %s\n", messageActionsEvent.Data.MessageTimetoken)
			case file := <-listener.File:
				fmt.Printf("file.File.PNMessage.Text: %s\n", file.File.PNMessage.Text)
				fmt.Printf("file.File.PNFile.Name: %s\n", file.File.PNFile.Name)
				fmt.Printf("file.File.PNFile.ID: %s\n", file.File.PNFile.ID)
				fmt.Printf("file.File.PNFile.URL: %s\n", file.File.PNFile.URL)
				fmt.Printf("file.Channel: %s\n", file.Channel)
				fmt.Printf("file.Timetoken: %d\n", file.Timetoken)
				fmt.Printf("file.SubscribedChannel: %s\n", file.SubscribedChannel)
				fmt.Printf("file.Publisher: %s\n", file.Publisher)
			}
		}
	}()
}
```

#### Remove listeners

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// removeListeners demonstrates removing event listeners
func removeListeners() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("myUniqueUserId"))
	pn := pubnub.NewPubNub(config)

	listener := pubnub.NewListener()

	pn.AddListener(listener)

	// some time later
	pn.RemoveListener(listener)
}
```

#### Handling disconnects

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// handlingDisconnects demonstrates handling disconnect events
func handlingDisconnects() {
	listener := pubnub.NewListener()

	go func() {
		for {
			select {
			case status := <-listener.Status:
				switch status.Category {
				case pubnub.PNDisconnectedCategory:
					// handle disconnect here
				}
			case <-listener.Message:
			case <-listener.Presence:
			}
		}
	}()
}
```

#### Listener status events

| Category | Description |
| --- | --- |
| `PNTimeoutCategory` | Processing has failed because of request time out. |
| `PNDisconnectedCategory` | The SDK is not able to reach PubNub servers because the machine or device are not connected to Internet or this has been lost, your ISP (Internet Service Provider) is having to troubles or perhaps or the SDK is behind of a proxy. |
| `PNConnectedCategory` | SDK subscribed with a new mix of channels (fired every time the channel / channel group mix changed). |
| `PNAccessDeniedCategory` | The SDK will announce this error when the Access Manager does not allow the subscription to a channel or a channel group. |
| `PNBadRequestCategory` | PubNub API server was unable to parse SDK request correctly. |
| `PNCancelledCategory` | Request was cancelled by user. |
| `PNLoopStopCategory` | Subscription loop has been stopped due some reasons. |
| `PNReconnectedCategory` | Subscription loop has been reconnected due some reasons. |
| `PNAcknowledgmentCategory` | An API call was successful. This status has additional details based on the type of the successful operation. |
| `PNReconnectionAttemptsExhausted` | The SDK loop has been stopped due maximum reconnection exhausted. |
| `PNNoStubMatchedCategory/PNUnknownCategory` | PNNoStubMatchedCategory as the StatusCategory means an unknown status category event occurred. |
| `PNRequestMessageCountExceededCategory` | `PNRequestMessageCountExceededCategory` is fired when the `MessageQueueOverflowCount` limit is exceeded by the number of messages received in a single subscribe request. |

## User ID

Use these functions to set or get a user ID at runtime.

### Method(s)

Set or get `UserId` with:

```go
config.SetUserId(UserId(string))
```

| Parameter | Description |
| --- | --- |
| `UserId` *Type: stringDefault: n/a | `UserId` to be used as a device identifier. If you don't set the `UserId`, you won't be able to connect to PubNub. |

```go
config.GetUserId()
```

This method doesn't take any arguments.

### Sample code

#### Set user ID

:::note Required User ID
Always set the `UserId` to uniquely identify the user or device that connects to PubNub. This `UserId` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UserId`, you won't be able to connect to PubNub.
:::

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setUserId demonstrates setting user ID
func Example_setUserId() {
	// Create a new configuration with initial user ID
	config := pubnub.NewConfigWithUserId(pubnub.UserId("initial-user"))

	// Set a new user ID after configuration creation
	config.SetUserId(pubnub.UserId("myUniqueUserId"))
}
```

#### Get user ID

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_getUserId demonstrates getting user ID
func Example_getUserId() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("myUniqueUserId"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	pn := pubnub.NewPubNub(config)

	// Get the user ID from configuration
	userId := config.GetUserId()

	if pn != nil {
		fmt.Printf("User ID: %s\n", userId)
	}

	// Output:
	// User ID: myUniqueUserId
}
```

## Authentication key

Set or get the user's authentication key.

### Method(s)

```go
config.AuthKey = string
```

| Parameter | Description |
| --- | --- |
| `AuthKey` *Type: string | If Access Manager is utilized, client will use this `AuthKey` in all restricted requests. |

```go
config.AuthKey
```

This method doesn't take any arguments.

### Sample code

#### Set auth key

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setAuthKey demonstrates setting authentication key
func Example_setAuthKey() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// Set authentication key for Access Manager
	config.AuthKey = "my_auth_key"
}
```

#### Get auth key

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_getAuthKey demonstrates getting authentication key
func Example_getAuthKey() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"
	config.AuthKey = "my_auth_key"

	pn := pubnub.NewPubNub(config)

	// Get the authentication key from configuration
	authKey := config.AuthKey

	if pn != nil {
		fmt.Printf("Auth key: %s\n", authKey)
	}

	// Output:
	// Auth key: my_auth_key
}
```

### Returns

None.

## Filter expression

:::note Requires Stream Controller add-on
This method requires that the *Stream Controller* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

Stream filtering lets a subscriber receive only messages that match a filter expression. The client sets the filter, and the server applies it to prevent unmatched messages from reaching the subscriber.

To set or get message filters, you can use the following methods. To learn more about filtering, refer to the [Publish Messages](https://www.pubnub.com/docs/general/messages/publish) documentation.

### Method(s)

```go
config.FilterExpression = string
```

| Parameter | Description |
| --- | --- |
| `filterExpression` *Type: string | PSV2 feature to `Subscribe` with a custom filter expression. |

```go
config.FilterExpression
```

This method doesn't take any arguments.

### Sample code

#### Set filter expression

:::note Required User ID
Always set the `UserId` to uniquely identify the user or device that connects to PubNub. This `UserId` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UserId`, you won't be able to connect to PubNub.
:::

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_setFilterExpression demonstrates using filter expressions for subscriptions
func Example_setFilterExpression() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	// snippet.hide
	config = setPubnubExampleConfigData(config)
	// snippet.show

	// Set filter expression to only receive messages matching the criteria
	config.FilterExpression = "language == 'english'"

	pn := pubnub.NewPubNub(config)

	if pn != nil && config.FilterExpression != "" {
		fmt.Println("Filter expression configured")
	}

	// Output:
	// Filter expression configured
}
```

#### Get filter expression

```go
// Replace with your package name (usually "main")
package pubnub_samples_test

import (
	"fmt"

	pubnub "github.com/pubnub/go/v8"
)

// Example_getFilterExpression demonstrates getting filter expression
func Example_getFilterExpression() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"
	config.FilterExpression = "language == 'english'"

	pn := pubnub.NewPubNub(config)

	// Get the filter expression from configuration
	filterExpr := config.FilterExpression

	if pn != nil {
		fmt.Printf("Filter expression: %s\n", filterExpr)
	}

	// Output:
	// Filter expression: language == 'english'
}
```

## Terms in this document

* **Access Manager** - A cryptographic, token-based permission administrator that allows you to regulate clients' access to PubNub resources, such as channels, channel groups, and user IDs.
* **Listener** - A function or objectthat reacts to events or messages, like new chat messages or connection updates, letting your app respond in real-time.
* **Message** - A unit of data transmitted between clients or between a client and a server in PubNub, containing information such as text, binary data, or structured data formats like JSON. Messages are sent over channels and can be tracked for delivery and read status.
* **Origin** - The subdomain used to establish a connection to the PubNub network that allows your application's traffic to appear like it's coming from your own domain.
* **PubNub** - PubNub is a real-time messaging platform that provides APIs and SDKs for building scalable applications. It handles the complex infrastructure of real-time communication, including: Message delivery and persistence, Presence detection, Access control, Push notifications, File sharing, Serverless processing with Functions and Events & Actions, Analytics and monitoring with BizOps Workspace, AI-powered insights with Illuminate.