---
source_url: https://www.pubnub.com/docs/data-storage/metadata/manage-user-metadata
title: Set, get, and remove user metadata
updated_at: 2026-09-30T07:20:08.000Z
---

# Set, get, and remove user metadata

## 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.

:::note Starting a new app? Use DataSync
[DataSync](https://www.pubnub.com/docs/data-storage/structured-data/overview.md) is the successor to App Context. It does everything App Context does for users, channels, and memberships, and adds typed schemas, partial updates with ETags, field-level access control, and per-class expiry. Refer to [How DataSync compares to App Context](https://www.pubnub.com/docs/data-storage/structured-data/overview.md) for a feature-by-feature comparison.
DataSync is currently available to new accounts and to accounts that are not actively using App Context. If your keysets already use App Context, keep using it for now. App Context remains fully supported and these pages stay accurate.
:::

This guide shows you how to give a single [user](https://www.pubnub.com/docs/architecture/core-concepts.md#user-id) its [App Context](https://www.pubnub.com/docs/data-storage/metadata/overview.md) metadata: set its built-in and custom fields, read them back, and remove the whole record. App Context must be enabled on the keyset before you call it, and new keysets don't enable it by default. To read or list every user's metadata at once instead of one user, refer to [Get metadata for all users](https://www.pubnub.com/docs/data-storage/metadata/get-metadata-for-all-users.md).

:::note User ID / UUID
User ID is also referred to as **UUID/uuid** in some APIs and server responses but **holds the value** of the **userId** parameter you [set during initialization](https://www.pubnub.com/docs/architecture/core-concepts.md).
:::

## Set user metadata

Call `Set UUID Metadata` with a `data` object holding built-in fields such as `name`, `email`, `externalId`, and `profileUrl`, plus any `custom` fields your application needs. If you omit the User ID, the call applies to the client's own User ID. The call creates the record if it doesn't exist yet, or updates it if it does.

:::warning Unsupported partial updates of custom metadata
The value of the custom metadata parameter sent in this method always overwrites the value stored on PubNub servers. If you want to add new custom data to an existing one, you must:
1. Get the existing metadata and store it locally.
2. Append the new custom metadata to the existing one.
3. Set the entire updated custom object.
:::

### JavaScript

```javascript
// Using UUID from the config  - default when uuid is not passed in the method
try {
  const response = await pubnub.objects.setUUIDMetadata({
    data: {
      name: 'John Doe',
    },
  });
  console.log('setUUIDMetadata response:', response);
} catch (error) {
  console.error(`Set UUID metadata error: ${error}`);
}

// Using the passed in UUID
try {
  const response = await pubnub.objects.setUUIDMetadata({
    uuid: 'myUuid',
    data: {
      email: 'john.doe@example.com',
    },
  });
  console.log('setUUIDMetadata response:', response);
} catch (error) {
  console.error(`Set UUID metadata error: ${error}`);
}
```

### Java

```java
PNSetUUIDMetadataResult pnSetUUIDMetadataResult = pubNub.setUUIDMetadata()
        .name("Foo")
        .profileUrl("http://example.com")
        .email("foo@example.com")
        .includeCustom(true)
        .sync();
```

### Kotlin

```kotlin
pubnub.setUUIDMetadata()
    .async { result ->
        result.onFailure { exception ->
            // Handle error
        }.onSuccess { value ->
            // Handle successful method result
        }
    }
```

### C#

```csharp
using PubnubApi;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = new Pubnub(pnConfiguration);
        
// Set Metadata for UUID set in the pubnub instance
PNResult<PNSetUuidMetadataResult> setUuidMetadataResponse = await pubnub.SetUuidMetadata()
    .Uuid(config.Uuid)
    .Name("John Doe")
    .Email("john.doe@user.com")
    .ExecuteAsync();
PNSetUuidMetadataResult setUuidMetadataResult = setUuidMetadataResponse.Result;
PNStatus status = setUuidMetadataResponse.Status;
```

### Go

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

import (
	"fmt"
	"time"

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

// Example_setUUIDMetadata demonstrates setting user metadata (UUID metadata)
func Example_setUUIDMetadata() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo" // Replace with your subscribe key
	config.PublishKey = "demo"   // Replace with your publish key

	pn := pubnub.NewPubNub(config)

	// Set user metadata with profile information
	response, status, err := pn.SetUUIDMetadata().
		UUID("user-123").                                // User ID
		Name("John Doe").                                // Display name
		Email("john.doe@example.com").                   // Email address
		ProfileURL("https://example.com/profiles/john"). // Profile URL
		ExternalID("ext-123").                           // External system ID
		Custom(map[string]interface{}{                   // Custom metadata
			"role":     "admin",
			"language": "en",
		}).
		Execute()

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	if status.StatusCode == 200 {
		fmt.Printf("User metadata set for UUID: %s\n", response.Data.ID)
	}

	// Output:
	// User metadata set for UUID: user-123
}
```

### Swift

```swift
// Set user metadata for a specific identifier
let userMetadataToSet = PubNubUserMetadataBase(
  metadataId: "some-id",
  name: "Some User",
  custom: ["department": "Engineering"]
)

pubnub.setUserMetadata(userMetadataToSet) { result in
  switch result {
  case let .success(userMetadata):
    print("The metadata for `\(userMetadata.metadataId)`: \(userMetadata)")
  case let .failure(error):
    print("Create request failed with error: \(error.localizedDescription)")
  }
}
```

### PHP

```php
foreach ($sampleUsers as $user) {
    $setUserMetadataResult = $pubnub->setUuidMetadata()
        ->uuid($user['id'])
        ->name($user['name'])
        ->email($user['email'])
        ->externalId($user['externalId'])
        ->profileUrl($user['profileUrl'])
        ->custom($user['custom'])
        ->sync();
    assert($setUserMetadataResult->getId());
    assert($setUserMetadataResult->getName() === $user['name']);
    assert($setUserMetadataResult->getEmail() === $user['email']);
    assert($setUserMetadataResult->getExternalId() === $user['externalId']);
    assert($setUserMetadataResult->getProfileUrl() === $user['profileUrl']);
    assert(json_encode($setUserMetadataResult->getCustom()) === json_encode($user['custom']));
}
```

### Unity

```csharp
using PubnubApi;
using PubnubApi.Unity;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = PubnubUnityUtils.NewUnityPubnub(pnConfiguration);

// If you're using Unity Editor setup you can get the Pubnub instance from PNManagerBehaviour
// For more details, see https://www.pubnub.com/docs/sdks/unity#configure-pubnub
/*
[SerializeField] private PNManagerBehaviour pubnubManager;
Pubnub pubnub = pubnubManager.pubnub;
*/

// Set Metadata for UUID set in the pubnub instance
PNResult<PNSetUuidMetadataResult> setUuidMetadataResponse = await pubnub.SetUuidMetadata()
    .Uuid(config.Uuid)
    .Name("John Doe")
    .Email("john.doe@user.com")
    .ExecuteAsync();
PNSetUuidMetadataResult setUuidMetadataResult = setUuidMetadataResponse.Result;
PNStatus status = setUuidMetadataResponse.Status;
```

If [Access Manager](https://www.pubnub.com/docs/security/access-control/overview.md) is enabled on your keyset, this call requires an `update` permission grant on that User ID. On success, the call also fires the `set` [App Context event](https://www.pubnub.com/docs/data-storage/metadata/events.md) other subscribers receive.

Pass the `eTag` from a get call as `ifMatchesEtag` on a set call to apply the update only if the record hasn't changed since you read it, so a mismatch returns HTTP 412. Most SDKs document this parameter on the same method as `ifMatchesEtag`. Check the API reference for your platform in [Available SDKs](https://www.pubnub.com/docs/sdks.md) for the exact name.

## Get user metadata

Call `Get UUID Metadata` to read a user's current record. Most PubNub SDKs default to the client's own User ID when you omit one, though some expect you to pass it explicitly. Most also include the `custom` object in the response by default. Check your platform's API reference in [Available SDKs](https://www.pubnub.com/docs/sdks.md) to confirm.

### JavaScript

```javascript
// Using UUID from the config  - default when uuid is not passed in the method
try {
  const response = await pubnub.objects.getUUIDMetadata();
  console.log('getUUIDMetadata response:', response);
} catch (error) {
  console.error(`Get UUID metadata error: ${error}`);
}

// Using the passed in UUID
try {
  const response = await pubnub.objects.getUUIDMetadata({
    uuid: 'myUuid',
  });
  console.log('getUUIDMetadata response:', response);
} catch (error) {
  console.error(`Get UUID metadata error: ${error}`);
}
```

### Java

```java
pubNub.getUUIDMetadata().async(result -> { /* check result */ });
```

### Kotlin

```kotlin
pubnub.getUUIDMetadata()
    .async { result ->
        result.onFailure { exception ->
            // Handle error
        }.onSuccess { value ->
            // Handle successful method result
        }
    }
```

### C#

```csharp
using PubnubApi;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = new Pubnub(pnConfiguration);
        
// Get Metadata for UUID set in the pubnub instance
PNResult<PNGetUuidMetadataResult> getUuidSetMetadataResponse = await pubnub.GetUuidMetadata()
    .ExecuteAsync();
PNGetUuidMetadataResult getUuidSetMetadataResult = getUuidSetMetadataResponse.Result;
PNStatus uuidSetStatus = getUuidSetMetadataResponse.Status;

// Get Metadata for a specific UUID
PNResult<PNGetUuidMetadataResult> getSpecificUuidMetadataResponse = await pubnub.GetUuidMetadata()
    .Uuid("my-uuid")
    .ExecuteAsync();
PNGetUuidMetadataResult getSpecificUuidMetadataResult = getSpecificUuidMetadataResponse.Result;
PNStatus specificUuidStatus = getSpecificUuidMetadataResponse.Status;
```

### Go

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

import (
	"fmt"
	"time"

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

// Example_getUUIDMetadata demonstrates retrieving user metadata
func Example_getUUIDMetadata() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	pn := pubnub.NewPubNub(config)

	// First, set user metadata
	pn.SetUUIDMetadata().
		UUID("user-456").
		Name("Jane Smith").
		Email("jane@example.com").
		Execute()

	// Small delay to ensure metadata is persisted before retrieval
	time.Sleep(2 * time.Second)

	// Then retrieve the user metadata
	response, status, err := pn.GetUUIDMetadata().
		UUID("user-456"). // User ID to retrieve
		Execute()

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	if status.StatusCode == 200 {
		fmt.Printf("User: %s\n", response.Data.Name)
		fmt.Printf("Email: %s\n", response.Data.Email)
	}

	// Output:
	// User: Jane Smith
	// Email: jane@example.com
}
```

### Swift

```swift
// Retrieve user metadata for a specific identifier
pubnub.fetchUserMetadata("some-id") { result in
  switch result {
  case let .success(userMetadata):
    print("The metadata for `\(userMetadata.metadataId)`: \(userMetadata)")
  case let .failure(error):
    print("Fetch request failed with error: \(error.localizedDescription)")
  }
}
```

### PHP

```php
$getUserMetadataResult = $pubnub->getUuidMetadata()
    ->uuid($sampleUsers[0]['id'])
    ->sync();
assert($getUserMetadataResult->getId() === $sampleUsers[0]['id']);
assert($getUserMetadataResult->getName() === $sampleUsers[0]['name']);
assert($getUserMetadataResult->getEmail() === $sampleUsers[0]['email']);
```

### Unity

```csharp
using PubnubApi;
using PubnubApi.Unity;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = PubnubUnityUtils.NewUnityPubnub(pnConfiguration);

// If you're using Unity Editor setup you can get the Pubnub instance from PNManagerBehaviour
// For more details, see https://www.pubnub.com/docs/sdks/unity#configure-pubnub
/*
[SerializeField] private PNManagerBehaviour pubnubManager;
Pubnub pubnub = pubnubManager.pubnub;
*/

// Get Metadata for UUID set in the pubnub instance
PNResult<PNGetUuidMetadataResult> getUuidSetMetadataResponse = await pubnub.GetUuidMetadata()
    .ExecuteAsync();
PNGetUuidMetadataResult getUuidSetMetadataResult = getUuidSetMetadataResponse.Result;
PNStatus uuidSetStatus = getUuidSetMetadataResponse.Status;

// Get Metadata for a specific UUID
PNResult<PNGetUuidMetadataResult> getSpecificUuidMetadataResponse = await pubnub.GetUuidMetadata()
    .Uuid("my-uuid")
    .ExecuteAsync();
PNGetUuidMetadataResult getSpecificUuidMetadataResult = getSpecificUuidMetadataResponse.Result;
PNStatus specificUuidStatus = getSpecificUuidMetadataResponse.Status;
```

If Access Manager is enabled, this call requires a `get` permission grant on that User ID. A User ID with no metadata record yet returns a not-found error, since setting a `userId` on a client doesn't create one.

## Remove user metadata

Call `Remove UUID Metadata` to delete a user's record entirely, including every custom field. There's no way to remove a single field without rewriting the record. Refer to [Set user metadata](#set-user-metadata) to overwrite `custom` with everything except the field you want gone.

### JavaScript

```javascript
// Using UUID from the config  - default when uuid is not passed in the method
try {
  const response = await pubnub.objects.removeUUIDMetadata();
} catch (error) {
  console.error(`Remove UUID metadata error: ${error}`);
}

// Using the passed in UUID
try {
  const response = await pubnub.objects.removeUUIDMetadata({
    uuid: 'myUuid',
  });
} catch (error) {
  console.error(`Remove UUID metadata error: ${error}`);
}
```

### Java

```java
pubNub.removeUUIDMetadata().async(result -> { /* check result */ });
```

### Kotlin

```kotlin
pubnub.removeUUIDMetadata()
    .async { result ->
        result.onFailure { exception ->
            // Handle error
        }.onSuccess { value ->
            // Handle successful method result
        }
    }
```

### C#

```csharp
using PubnubApi;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = new Pubnub(pnConfiguration);
        
// Remove Metadata for UUID set in the pubnub instance
PNResult<PNRemoveUuidMetadataResult> removeUuidMetadataResponse = await pubnub.RemoveUuidMetadata()
    .ExecuteAsync();
PNRemoveUuidMetadataResult removeUuidMetadataResult = removeUuidMetadataResponse.Result;
PNStatus status = removeUuidMetadataResponse.Status;
```

### Go

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

import (
	"fmt"
	"time"

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

// Example_removeUUIDMetadata demonstrates removing user metadata
func Example_removeUUIDMetadata() {
	config := pubnub.NewConfigWithUserId(pubnub.UserId("demo-user"))
	config.SubscribeKey = "demo"
	config.PublishKey = "demo"

	pn := pubnub.NewPubNub(config)

	// Remove user metadata
	_, status, err := pn.RemoveUUIDMetadata().
		UUID("user-to-remove"). // User ID to remove
		Execute()

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	if status.StatusCode == 200 {
		fmt.Println("User metadata removed successfully")
	}

	// Output:
	// User metadata removed successfully
}
```

### Swift

```swift
// Remove user metadata for a specific identifier
pubnub.removeUserMetadata("some-id") { result in
  switch result {
  case let .success(metadataId):
    print("The metadata has been removed for the identifier `\(metadataId)`")
  case let .failure(error):
    print("Delete request failed with error: \(error.localizedDescription)")
  }
}
```

### PHP

```php
$removeUserMetadataResult = $pubnub->removeUuidMetadata()
    ->uuid($sampleUsers[1]['id'])
    ->sync();
assert($removeUserMetadataResult);
```

### Unity

```csharp
using PubnubApi;
using PubnubApi.Unity;

// Configuration
PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUniqueUserId"))
{
    SubscribeKey = "demo",
    PublishKey = "demo",
    Secure = true
};

// Initialize PubNub
Pubnub pubnub = PubnubUnityUtils.NewUnityPubnub(pnConfiguration);

// If you're using Unity Editor setup you can get the Pubnub instance from PNManagerBehaviour
// For more details, see https://www.pubnub.com/docs/sdks/unity#configure-pubnub
/*
[SerializeField] private PNManagerBehaviour pubnubManager;
Pubnub pubnub = pubnubManager.pubnub;
*/

// Remove Metadata for UUID set in the pubnub instance
PNResult<PNRemoveUuidMetadataResult> removeUuidMetadataResponse = await pubnub.RemoveUuidMetadata()
    .ExecuteAsync();
PNRemoveUuidMetadataResult removeUuidMetadataResult = removeUuidMetadataResponse.Result;
PNStatus status = removeUuidMetadataResponse.Status;
```

If Access Manager is enabled, this call requires a `delete` permission grant on that User ID. Turning on **Enforce referential integrity for memberships** in the Admin Portal also deletes every membership pointing at this User ID when you remove its metadata. Leaving that setting off leaves those memberships in place, pointing at a User ID with no metadata record. Refer to [Membership connects users and channels](https://www.pubnub.com/docs/data-storage/metadata/overview.md#membership-connects-users-and-channels) for the full referential-integrity behavior.

## Set, get, and remove user metadata without code

[BizOps Workspace](https://www.pubnub.com/docs/data-storage/metadata/overview.md)'s **User Management** module performs the same three operations from the Admin Portal, with no SDK call required:

* [Create users](https://www.pubnub.com/docs/data-storage/metadata/manage-user-metadata.md). Set a new user's `name`, `email`, and custom fields.
* [Update users](https://www.pubnub.com/docs/data-storage/metadata/manage-user-metadata.md). Change an existing user's fields.
* [Delete users](https://www.pubnub.com/docs/data-storage/metadata/manage-user-metadata.md). Remove a user's metadata, including in bulk.

A record you create, edit, or delete in BizOps Workspace is the same record your SDK calls read and write. Changes in either place are immediately visible in the other.

## Related tasks

* [App Context](https://www.pubnub.com/docs/data-storage/metadata/overview.md). The three entity types and how App Context relates to messages and [Presence](https://www.pubnub.com/docs/presence/overview.md).
* [Get metadata for all users](https://www.pubnub.com/docs/data-storage/metadata/get-metadata-for-all-users.md). Page through every user's metadata instead of one.
* [Set, get, and remove memberships](https://www.pubnub.com/docs/data-storage/metadata/manage-memberships.md). Manage this user's channel list.
* [App Context events](https://www.pubnub.com/docs/data-storage/metadata/events.md). The `set` and `delete` event payload this operation produces.
* [App Context API limits](https://www.pubnub.com/docs/data-storage/metadata/api-limits.md). Field-length limits for `name`, `email`, and `custom`.

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