---
source_url: https://www.pubnub.com/docs/data-storage/structured-data/create-entities-and-relationships
title: Create entities and relationships
updated_at: 2026-09-30T07:20:08.000Z
---

# Create entities and relationships

## 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 create DataSync objects: entities, relationships, users, channels, and memberships. All creates require a valid [Access Manager](https://www.pubnub.com/docs/security/access-control/overview.md) token. Refer to [Grant DataSync access](https://www.pubnub.com/docs/data-storage/structured-data/grant-structured-data-access.md) if you don't have a token yet.

## Before you start

* DataSync must be enabled on your keyset. Refer to [Enable DataSync](https://www.pubnub.com/docs/data-storage/structured-data/enable-structured-data.md).
* The class you're creating an instance of must exist on the keyset. Refer to [Define an entity class](https://www.pubnub.com/docs/data-storage/structured-data/define-entity-class.md).
* Access Manager must be enabled and your client must have a token with `create` permission on the target resource type.

## Create an entity

Supply the class name, the class version, and optionally an `id`, a `status`, and a payload.

### JavaScript

```javascript
const response = await pubnub.dataSync.createEntity({
    id: 'product-sneaker-42',
    class: 'Product',
    data: {
        classVersion: 1,
        payload: { name: 'Retro Sneaker', price: 89.99, stock: 12 },
    },
})
```

### C#

```csharp
PNResult<PNDataSyncEntityResult> response = await pubnub.DataSync.CreateEntity(new CreateEntityParameters
{
    Id = "product-sneaker-42",
    EntityClass = "Product",
    EntityClassVersion = 1,
    Payload = new Dictionary<string, object>
    {
        { "name", "Retro Sneaker" },
        { "price", 89.99 },
        { "stock", 12 },
    },
});
```

Using the REST API directly:

```bash
curl -X POST 'https://ps.pndsn.com/v1/datasync/subkeys/{subKey}/entities?auth=<token>&uuid=catalog-service' \
  -H 'Content-Type: application/vnd.pubnub.objects.entity+json;version=1' \
  -d '{
    "data": {
      "id": "product-sneaker-42",
      "entityClass": "Product",
      "entityClassVersion": 1,
      "payload": { "name": "Retro Sneaker", "price": 89.99, "stock": 12 }
    }
  }'
```

Set `uuid` to the user ID the token was granted to, `catalog-service` in this example. If `uuid` doesn't match the token's authorized user ID, Access Manager rejects the request with a `403`. The SDKs send `uuid` for you.

If you omit `id`, the server generates a UUID for you. If you supply an `id` that already exists, the request is rejected with a `409 Conflict`.

Refer to [Create entity (JavaScript)](https://www.pubnub.com/docs/sdks/javascript/api-reference/data-sync.md#create-entity), [Create entity (C#)](https://www.pubnub.com/docs/sdks/c-sharp/api-reference/data-sync.md#create-entity), and [Create entity (REST)](https://www.pubnub.com/docs/sdks/rest-api/create-entity.md) for the full parameter reference.

## Create a user

A user requires only the class version. The class name defaults to `User`. This example uses `MarketplaceUser`, the subclass from [Extend a Global class](https://www.pubnub.com/docs/data-storage/structured-data/define-entity-class.md#extend-a-global-class).

### JavaScript

```javascript
const created = await pubnub.dataSync.createUser({
    id: 'user-alice',
    class: 'MarketplaceUser',
    data: {
        classVersion: 1,
        payload: {
            name: 'Alice',
            type: 'shopper',
            display_name: 'Alice',
        },
    },
})
```

### C#

```csharp
PNResult<PNDataSyncUserResult> created = await pubnub.DataSync.CreateUser(new CreateUserParameters
{
    Id = "user-alice",
    EntityClass = "MarketplaceUser",
    EntityClassVersion = 1,
    Payload = new Dictionary<string, object>
    {
        { "name", "Alice" },
        { "type", "shopper" },
        { "display_name", "Alice" },
    },
});
```

The payload leaves out `email` on purpose. `email` belongs only to the `admin` projection, and a client token without that projection can't write it. The request fails with a `403` and error code `DS-0202`. Set admin-only fields from your server. Refer to [Projections](https://www.pubnub.com/docs/data-storage/structured-data/projections.md).

Refer to [Create user (JavaScript)](https://www.pubnub.com/docs/sdks/javascript/api-reference/data-sync.md#create-user), [Create user (C#)](https://www.pubnub.com/docs/sdks/c-sharp/api-reference/data-sync.md#create-user), and [Create user (REST)](https://www.pubnub.com/docs/sdks/rest-api/create-user.md) for the full parameter reference.

## Create a channel

A channel requires only the class version. The class name defaults to `Channel`.

### JavaScript

```javascript
const channel = await pubnub.dataSync.createChannel({
    id: 'channel-summer-sale',
    data: {
        classVersion: 1,
        payload: { name: 'Summer Sale', type: 'promotion' },
    },
})
```

### C#

```csharp
PNResult<PNDataSyncChannelResult> channel = await pubnub.DataSync.CreateChannel(new CreateChannelParameters
{
    Id = "channel-summer-sale",
    EntityClassVersion = 1,
    Payload = new Dictionary<string, object>
    {
        { "name", "Summer Sale" },
        { "type", "promotion" },
    },
});
```

Refer to [Create channel (REST)](https://www.pubnub.com/docs/sdks/rest-api/create-channel.md) for the request and response reference.

:::warning A channel entity is not a pub/sub channel
Creating a channel entity doesn't create or configure the underlying Pub/Sub channel. The entity holds metadata. Messaging works whether or not the entity exists. Refer to [Built-in types](https://www.pubnub.com/docs/data-storage/structured-data/built-in-types.md#channels).
:::

## Create a membership

A membership requires `channelId`, `userId`, and `relationshipClassVersion`. Both the channel and the user must already exist.

### JavaScript

```javascript
const membership = await pubnub.dataSync.createMembership({
    id: 'membership-alice-summer-sale',
    userId: 'user-alice',
    channelId: 'channel-summer-sale',
    data: {
        classVersion: 1,
        payload: { role: 'viewer' },
    },
})
```

### C#

```csharp
PNResult<PNDataSyncMembershipResult> membership = await pubnub.DataSync.CreateMembership(new CreateMembershipParameters
{
    Id = "membership-alice-summer-sale",
    ChannelId = "channel-summer-sale",
    UserId = "user-alice",
    MembershipClassVersion = 1,
    Payload = new Dictionary<string, object> { { "role", "viewer" } },
});
```

Using the REST API directly:

```bash
curl -X POST 'https://ps.pndsn.com/v1/datasync/subkeys/{subKey}/memberships?auth=<token>&uuid=catalog-service' \
  -H 'Content-Type: application/vnd.pubnub.objects.membership+json;version=1' \
  -d '{
    "data": {
      "channelId": "channel-summer-sale",
      "userId": "user-alice",
      "relationshipClassVersion": 1,
      "payload": { "role": "viewer" }
    }
  }'
```

If the channel or the user doesn't exist, the request returns a `404`. A duplicate membership returns a `409`.

Refer to [Create membership (REST)](https://www.pubnub.com/docs/sdks/rest-api/create-membership.md) for the full parameter reference.

## Create a relationship

A relationship links two entities through a relationship class you define. This example adds `product-sneaker-42` to Alice's wishlist through the `Wishlist` class from [Define a relationship class](https://www.pubnub.com/docs/data-storage/structured-data/define-entity-class.md#define-a-relationship-class). Both entities must already exist, and each must match the class that its side of the relationship allows.

### JavaScript

```javascript
const relationship = await pubnub.dataSync.createRelationship({
    id: 'wishlist-alice-sneaker',
    class: 'Wishlist',
    entityAId: 'user-alice',
    entityBId: 'product-sneaker-42',
    data: {
        classVersion: 1,
        payload: { addedFrom: 'summer-sale' },
    },
})
```

### C#

```csharp
PNResult<PNDataSyncRelationshipResult> relationship = await pubnub.DataSync.CreateRelationship(new CreateRelationshipParameters
{
    Id = "wishlist-alice-sneaker",
    RelationshipClass = "Wishlist",
    RelationshipClassVersion = 1,
    EntityAId = "user-alice",
    EntityBId = "product-sneaker-42",
    Payload = new Dictionary<string, object> { { "addedFrom", "summer-sale" } },
});
```

`entityAId` must be a `MarketplaceUser` and `entityBId` must be a `Product`, because the `Wishlist` class restricts both sides. An entity of another class is rejected with a `400` and error code `DS-0800`.

Refer to [Create relationship (REST)](https://www.pubnub.com/docs/sdks/rest-api/create-relationship.md) for the full parameter reference.

## Related tasks

* [Use optimistic concurrency with ETags](https://www.pubnub.com/docs/data-storage/structured-data/data-operations.md#optimistic-concurrency-with-etags). Protect updates and deletes from stale writes.

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