# Named Users

A Named User is a proprietary identifier that maps customer-chosen IDs, e.g., CRM data, to Channels. It is useful to think of a Named User as an individual consumer who might have more than one mobile device registered with your app. For example, Named User "john_doe_123" might have a personal Android phone and an iPad, on both of which he has opted in for push notifications. If you want to reach John on both devices, associate the Channel (device) identifiers for each device to the Named User "john_doe_123," and push to the Named User. Notifications will then fan out to each associated device.


## Named User listing or lookup {#getnameduser}

Return a list of Named Users or look up a single Named User by `named_user_id`.

[Jump to examples ↓](#getnameduser-examples)

### `GET /api/named_users`

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Query parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `id` | `string` |  | The `named_user_id` you want to look up. When querying a `named_user_id`, the response contains a single `named_user` object.  If you do not query a specific `named_user_id`, the response returns an array of `named_users`, in which each object represents an individual Named User. |

**Responses**

**`200`** Returns OK for success.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

**One of:**

  - **`named_user`** `object` <[Named User object]({{< ref "/developer/rest-api/ua/schemas/named-user/" >}}#nameduserresponsebody)>

    The response body for a Named User listing, including tags, channels and attributes associated with the Named User.

  - **`ok`** `boolean` **REQUIRED**

    Success.

  - **`named_users`** `array` <[Named User object]({{< ref "/developer/rest-api/ua/schemas/named-user/" >}}#nameduserresponsebody)>
  - **`next_page`** `string`

    There might be more than one page of results for this listing. Follow this URL if it is present to the next page of results.

    Format: `url`

    Example: `https://go.urbanairship.com/api/named_users?start=john_doe`

  - **`ok`** `boolean` **REQUIRED**

    Success.


**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`404`** The requested resource doesn't exist.

Response body:

**Content-Type:** `application/vnd.urbanairship+json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example Named User lookup*

```http
GET /api/named_users/?id=user-456 HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
  "ok": true,
  "named_user": {
      "named_user_id": "user-456",
      "created" : "2020-04-08T20:41:06",
      "last_modified" : "2020-05-01T18:00:27",
      "tags": {
        "my_fav_tag_group": [
            "tag1",
            "tag2"
        ]
      },
      "subscription_lists": [
        {
          "list_ids": ["example_listId-1", "example_listId-5"],
          "scope": "web"
        },
        {
          "list_ids": ["example_listId-2", "example_listId-3"],
          "scope": "app"
        },
        {
          "list_ids": ["example_listId-2"],
          "scope": "web"
        },
        {
          "list_ids": ["example_listId-3"],
          "scope": "email"
        },
        {
          "list_ids": ["example_listId-4"],
          "scope": "sms"
        }
      ],
      "attributes": {
        "item_purchased": "Fur removal tool",
        "cats_name": "Sammy",
        "pets_age": 12
      },
      "user_attributes": {
        "ua_country": "US",
        "ua_language": "en",
        "ua_tz": "America/Los_Angeles"
      },
      "channels": [
        {
            "channel_id": "dceafd02-b852-4305-83df-98b65fa40dd4",
            "device_type": "ios",
            "installed": true,
            "opt_in": true,
            "push_address": "FFFF",
            "created": "2020-04-08T20:41:06",
            "last_registration": "2020-05-01T18:00:27",
            "tags": [
              "meow"
            ]
        }
      ]
  }
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserListingRequest request = NamedUserListingRequest.newRequest("user-456");
Response<NamedUserListingResponse> response = client.execute(request);
NamedUserView namedUser = response.getBody().get().getNamedUserView().get();

// The Named User ID
String namedUserId = namedUser.getNamedUserId();

// Map of tag groups and the associated sets of tags
ImmutableMap<String, ImmutableSet<String>> namedUserTags = namedUser.getNamedUserTags();

// All channel objects associated with the Named User
ImmutableSet<ChannelView> channelViews = namedUser.getChannelViews();

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-456')
response = named_user.lookup()
print(response)

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.named_user_id = 'user-456'
user = named_user.lookup

```

*Example Named User listing*

```http
GET /api/named_users HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3

```

```http
HTTP/1.1 200 OK
Data-Attribute: named_users
Link: <https://go.urbanairship.com/api/named_users?start=user-1234>; rel=next
Content-Type: application/vnd.urbanairship+json; version=3

{
   "next_page": "https://go.urbanairship.com/api/named_users?start=user-1234",
   "named_users": [
      {
         "named_user_id": "user-id-1234",
         "created" : "2020-04-08T20:41:06",
         "last_modified" : "2020-05-01T18:00:27",
         "tags": {
            "my_fav_tag_group": ["tag1", "tag2"]
         },
         "subscription_lists": [
         {
            "list_ids": ["example_listId-1", "example_listId-5"],
            "scope": "web"
         },
         {
            "list_ids": ["example_listId-2", "example_listId-3"],
            "scope": "app"
         },
         {
            "list_ids": ["example_listId-2"],
            "scope": "web"
         },
         {
            "list_ids": ["example_listId-3"],
            "scope": "email"
         }
         ],
         "attributes":{
            "item_purchased":"Fur removal tool",
            "cats_name":"fluffy butt",
            "pets_age":2
         },
         "user_attributes": {
            "ua_country": "US",
            "ua_language": "en",
            "ua_tz": "America/Los_Angeles"
         },
         "channels": [
            {
               "channel_id": "dceafd02-b852-4305-83df-98b65fa40dd5",
               "device_type": "ios",
               "installed": true,
               "opt_in": true,
               "push_address": "FFFF",
               "created": "2020-04-08T20:41:06",
               "last_registration": "2020-05-01T18:00:27",
               "alias": "xxxx",
               "tags": ["asdf"],
               "ios": {
                  "badge": 0,
                  "quiettime": {
                     "start": "22:00",
                     "end": "06:00"
                  },
                  "tz": "America/Los_Angeles"
               }
            }
         ]
      }
   ]
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserListingRequest request = NamedUserListingRequest.newRequest();
Response<NamedUserListingResponse> response = client.execute(request);
ImmutableList<NamedUserView> namedUsers = response.getBody().get().getNamedUserViews().get();

```

```python
from urbanairship import (
    BasicAuthClient, NamedUserList
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user_list = NamedUserList(airship=client)

for n in named_user_list:
    print(n.named_user_id)

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user_list = UA::NamedUserList.new(client: airship)
named_user_list.each do |named_user|
    puts(named_user)
end

```

---

## Named User update {#updatenameduser}

Create or update a Named User by associating/disassociating channels and
adding/removing tags and attributes in a single request.


[Jump to examples ↓](#updatenameduser-examples)

### `POST /api/named_users/{named_user_id}`

{{< warning >}}
If a channel has an assigned Named User and you make an additional
call to associate that same channel with a new Named User, the
original Named User association will be removed and the new Named User
and associated data will take its place. Additionally, all tags
associated to the original Named User cannot be used to address this
channel unless they are also associated with the new Named User.

{{< /warning >}}

{{< important >}}
We support up to 1,000 tags per Named User. Adding more than 1,000 tags per Named User can cause latency and service interruptions.
We strongly recommend removing unused tags whenever possible, and using Custom Events when appropriate.
Please [contact Support](https://support.airship.com/) if you believe your use case requires more than 1,000 tags per Named User, and they will help you find an alternative.

{{< /important >}}

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `named_user_id` | `string` | Required | A string value identifying the user, without leading or trailing whitespace. If this value contains reserved or special characters they must be URL encoded.  |

**Request body**

**Content-Type:** `application/json`

[Named User update payload]({{< ref "/developer/rest-api/ua/schemas/named-user/" >}}#nameduserupdate)

**Responses**

**`200`** Request was accepted.


Response body:

**Content-Type:** `application/json`

- **`attribute_warnings`** `string`

  Warnings encountered when processing attributes for this Named User.


- **`ok`** `boolean` **REQUIRED**

  Set to `true` when status code is `200`.


- **`tag_warnings`** `string`

  Warnings encountered when processing tags for this Named User.


**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Create a Named User by associating an email and SMS channel and setting tags and attributes.
*

```http
POST /api/named_users/john_doe HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "associate": [
      {
        "email_address": "john@example.com"
      },
      {
        "channel_id": "f5346fa3-99f1-496d-be37-2895ef58f5a5",
        "device_type": "sms"
      }
  ],
  "tags": {
      "set": {
          "subscription_status": ["gold"],
          "favorites" : ["sports", "stocks"]
      }
  },
  "attributes": [
    {
      "action": "set",
      "key": "name",
      "value": "John"
    }
  ]
}

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

associate = [
  {"email_address": "john@example.com"},
  {"channel_id": "f5346fa3-99f1-496d-be37-2895ef58f5a5", "device_type": "sms"}
]
tags = {
  "set": {
      "subscription_status": ["gold"],
      "favorites" : ["sports", "stocks"]
      }
}
attributes = [
    {
      "action": "set",
      "key": "name",
      "value": "John"
    }
  ]

named_user = NamedUser(
  airship=client,
  named_user_id="john_doe"
)

response = named_user.update(
  associate=associate,
  tags=tags,
  attributes=attributes
)

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserUpdateChannel namedUserUpdateChannel = NamedUserUpdateChannel.newBuilder()
        .addChannel(NamedUserUpdateDeviceType.ANDROID_CHANNEL, "aa2ae18c-f4b0-48ac-a859-55f26d2a7439")
        .build();

Attribute lastName = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("pseudo")
        .setValue("Pataki")
        .build();

NamedUserUpdatePayload namedUserUpdatePayload = NamedUserUpdatePayload.newBuilder()
        .addAttribute(lastName)
        .addTags("go", List.of("test1","test2"))
        .removeTags("go",List.of("test3","test4"))
        .addNamedUserUpdateChannel(namedUserUpdateChannel)
        .setAction(NamedUserUpdateChannelAction.ASSOCIATE)
        .build();

NamedUserUpdateRequest request = NamedUserUpdateRequest.newRequest("john", namedUserUpdatePayload);
Response<NamedUserUpdateResponse> response = client.execute(request);

```

---

## Named Users association {#associatenameduser}

Associate a channel or email address with a Named User (`named_user_id`). If the `named_user_id` does not already exist, this operation will create it. If the `channel_id` or `email address` is already associated with the `named_user_id`, this operation will do nothing.

[Jump to examples ↓](#associatenameduser-examples)

### `POST /api/named_users/associate`

{{< warning >}}
If a channel has an assigned Named User and you make an additional call to associate that same channel with a new Named User, the original Named User association will be removed and the new Named User and associated data will take its place. Additionally, all tags associated to the original Named User cannot be used to address this channel unless they are also associated with the new Named User.
{{< /warning >}}

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Request body**

Named User association requires a `channel_id` or `email_address`. Do not provide both in the same request. You can associate up to 100 Channel IDs to a Named User. Channel creation is asynchronous, so when associating a newly created channel, both a Channel ID and a device type are required to prevent "channel does not exist" errors.

**Content-Type:** `application/json`

**One of:**

  - **`channel_id`** `string` **REQUIRED**

    The Channel ID you want to associate with a Named User.

    Format: `uuid`

    Example: `9c36e8c7-5a73-47c0-9716-99fd3d4197d5`

  - **`device_type`** `string`

    The device type of the channel.

    Possible values: `ios`, `android`, `amazon`, `web`, `open`, `email`, `sms`

  - **`named_user_id`** `string` **REQUIRED**

    A string value identifying the user, without leading or trailing whitespace.

    Min length: 1, Max length: 128

    Example: `john_doe`

  - **`email_address`** `string` **REQUIRED**

    The email address you want to associate with a Named User.

    Format: `email`

    Example: `user@example.com`

  - **`named_user_id`** `string` **REQUIRED**

    The existing Named User ID

    Min length: 1, Max length: 128

    Example: `john_doe`


**Responses**

**`200`** The request was accepted but is not guaranteed to be successfully processed.
If the Named User has more than 1,000 channels associated with it, the request will be ignored.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[OK response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#okresponseobject)

**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`406`** Return when the client requests a version of the API that cannot be satisfied, because no compatible version is currently deployed.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example associate an iOS channel with a Named User*

```http
POST /api/named_users/associate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "channel_id": "df6a6b50-9843-0304-d5a5-743f246a4946",
   "device_type": "ios",
   "named_user_id": "user-id-1234"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserRequest request = NamedUserRequest.newAssociationRequest()
        .setChannel("df6a6b50-9843-0304-d5a5-743f246a4946", ChannelType.IOS)
        .setNamedUserId("user-id-1234");

Response<GenericResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-id-1234')
response = named_user.associate(channel_id='df6a6b50-9843-0304-d5a5-743f246a4946', device_type='ios')

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.named_user_id = 'user-id-1234'
named_user.associate(channel_id: 'df6a6b50-9843-0304-d5a5-743f246a4946', device_type: 'ios')

```

*Example associate a web channel with Named User (do not declare device type)*

```http
POST /api/named_users/associate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "channel_id": "wf6a6b50-9843-0304-d5a5-743f246a4946",
   "named_user_id": "user-id-1234"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserRequest request = NamedUserRequest.newAssociationRequest()
        .setChannel("wf6a6b50-9843-0304-d5a5-743f246a4946", ChannelType.WEB)
        .setNamedUserId("user-id-1234");

Response<GenericResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-id-1234')
response = named_user.associate(channel_id='wf6a6b50-9843-0304-d5a5-743f246a4946')

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.named_user_id = 'user-id-1234'
named_user.associate(channel_id: 'wf6a6b50-9843-0304-d5a5-743f246a4946')

```

*Example associate an email channel with Named User*

```http
POST /api/named_users/associate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "email_address": "monopoly.man@example.com",
   "named_user_id": "user-id-1234"
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-id-1234')
response = named_user.email_associate(email_address='monopoly.man@example.com')

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserRequest request = NamedUserRequest.newAssociationRequest()
        .setChannel("em6a6b50-9843-0304-d5a5-743f246a4946", ChannelType.EMAIL)
        .setNamedUserId("user-id-1234");

Response<GenericResponse> response = client.execute(request);

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.named_user_id = 'user-id-1234'
named_user.associate(channel_id: 'em6a6b50-9843-0304-d5a5-743f246a4946')

```

---

## Named Users disassociation {#disassociatednameduser}

Disassociate a channel or an email address from a `named_user_id`.

[Jump to examples ↓](#disassociatednameduser-examples)

### `POST /api/named_users/disassociate`

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Request body**

**Content-Type:** `application/json`

**One of:**

  - **`channel_id`** `string` **REQUIRED**

    The Channel ID you want to disassociate from a Named User.

    Format: `uuid`

    Example: `9c36e8c7-5a73-47c0-9716-99fd3d4197d5`

  - **`device_type`** `string`

    The device type of the channel.

    Possible values: `ios`, `android`, `amazon`, `web`, `email`, `sms`, `open`

  - **`named_user_id`** `string`

    The existing Named User ID.

    Min length: 1, Max length: 128

    Example: `john_doe`

  - **`email_address`** `string` **REQUIRED**

    The email address you want to disassociate from a Named User.

    Format: `email`

    Example: `user@example.com`

  - **`named_user_id`** `string`

    A string value identifying the new user with no leading or trailing whitespace. If the `named_user_id` does not already exist, this operation will create a new Named User and associate the `channel_id` with it.

    Min length: 1, Max length: 128

    Example: `john_doe`


**Responses**

**`200`** The request was accepted but is not guaranteed to be successfully processed.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[OK response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#okresponseobject)

**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`406`** Return when the client requests a version of the API that cannot be satisfied, because no compatible version is currently deployed.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example*

```http
POST /api/named_users/disassociate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "channel_id": "df6a6b50-9843-0304-d5a5-743f246a4946",
   "device_type": "ios",
   "named_user_id": "user-id-1234"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserRequest request = NamedUserRequest.newDisassociationRequest()
        .setChannel("df6a6b50-9843-0304-d5a5-743f246a4946", ChannelType.IOS);

Response<GenericResponse> response = client.execute(request);

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.disassociate(channel_id: 'df6a6b50-9843-0304-d5a5-743f246a4946', device_type: 'ios')

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-id-1234')
response = named_user.disassociate(channel_id='df6a6b50-9843-0304-d5a5-743f246a4946', device_type='ios')

```

*Example disassociate an email channel from Named User*

```http
POST /api/named_users/disassociate HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "email_address": "monopoly.man@example.com",
   "named_user_id": "user-id-1234"
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-id-1234')
response = named_user.email_disassociate(email_address='monopoly.man@example.com')

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserRequest request = NamedUserRequest.newDisassociationRequest()
        .setChannel("em6a6b50-9843-0304-d5a5-743f246a4946", ChannelType.EMAIL)
        .setNamedUserId("user-id-1234");

Response<GenericResponse> response = client.execute(request);

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user = UA::NamedUser.new(client: airship)
named_user.disassociate(channel_id: 'em6a6b50-9843-0304-d5a5-743f246a4946')

```

---

## Named Users tags {#modifynamedusertags}

Add, remove, or set tags on a Named User. A single request body may contain add and/or remove objects or a single set field. At least one of the add, remove, or set objects must be present in a request.

[Jump to examples ↓](#modifynamedusertags-examples)

### `POST /api/named_users/tags`

{{< important >}}
A tag must be < 128 characters. A request with one or more tags longer than 128 characters will return a 400 response.
We support up to 1,000 tags per Named User. Adding more than 1,000 tags per Named User can cause latency and service interruptions. We strongly recommend removing unused tags whenever possible, and using Custom Events when appropriate. Please [contact Support](https://support.airship.com/) if you believe your use case requires more than 1,000 tags per Named User, and they will help you find an alternative.
{{< /important >}}

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Request body**

**Content-Type:** `application/json`

- **`add`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Add the list of tags to the Named User(s), but do not remove any. If the tags are already present, they are not modified.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

- **`audience`** `object` **REQUIRED**

  The Named User(s) you want to associate/disassociate tags with.

  **OBJECT PROPERTIES**

  - **`named_user_id`** `array[string]`

    Min items: 1, Max items: 1000

- **`remove`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Remove the list of tags from the Named User(s), but do not remove any others. If the tags are not currently present, nothing happens.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

- **`set`** `object` <[Tag Group object]({{< ref "/developer/rest-api/ua/schemas/tags/" >}}#taggroupobject)>

  Set these tags for the audience; any tags previously associated with the audience tags that are not in this current list are removed.

  Tags belong to Tag Groups. Tag Groups appear within the `tags` object for a Named User or the `tag_groups` object for a channel. See also [Device Properties](/docs/reference/data-collection/device-properties/)
``ua_`` is a reserved prefix for Airship-specific tag groups.

A Tag Group has two parts: a "name" string of 1-128 characters, and an array of tags, containing 0-100 tags. Each tag in the array is also a string consisting of 1-128 characters.

**Responses**

**`200`** If a tag request is partially valid, i.e., at least one tag group exists and is active, a 200 will be returned with a
warning in the response about the tag groups that failed to update. The tag groups listed in the warning will be CSV-formatted.


Response body:

**Content-Type:** `application/json`

- **`ok`** `boolean` **REQUIRED**

  Set to `true` when status code is `200`.


- **`tag_warnings`** `string`

  Warnings encountered when processing tags for this Named User.


**`400`** Parsing or validating the request failed. You will see this error if the same tag is present in both the add and remove fields.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`406`** Return when the client requests a version of the API that cannot be satisfied, because no compatible version is currently deployed.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example*

```http
POST /api/named_users/tags HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
  "audience": {
      "named_user_id": [
        "user-1",
        "user-2",
        "user-3"
      ]
  },
  "add": {
      "crm": [
        "tag1",
        "tag2",
        "tag3"
      ],
      "loyalty": [
        "tag1",
        "tag4",
        "tag5"
      ]
  },
  "remove": {
      "loyalty": [
        "tag6",
        "tag7"
      ]
  }
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserTagRequest request = NamedUserTagRequest.newRequest()
        .addNamedUsers("user-1", "user-2", "user-3")
        .addTags("crm", ImmutableSet.of("tag1", "tag2", "tag3"))
        .addTags("loyalty", ImmutableSet.of("tag1", "tag4", "tag5"))
        .removeTags("loyalty", ImmutableSet.of("tag6", "tag7"));

Response<GenericResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
named_user = NamedUser(airship=client, named_user_id='user-1')

resp1 = named_user.tag(
    group='loyalty',
    add=['tag2', 'tag3', 'tag4'],
    remove='tag1'
)

resp2 = named_user.tag(
    group='crm',
    set=['tag5', 'tag6']
)

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user_tags = UA::NamedUserTags.new(client: airship)
named_user_ids = ['user-1', 'user-2', 'user-3']
named_user_tags.set_audience(user_ids: named_user_ids)
named_user_tags.add(group_name: 'crm', tags: ['tag1', 'tag2', 'tag3'])
named_user_tags.remove(group_name: 'loyalty', tags: ['tag6', 'tag7'])
named_user_tags.send_request

```

---

## Named Users uninstall {#uninstallnameduser}

Disassociate and delete all channels associated with the named_user_id(s) and also delete the named_user_id(s). This call removes all channels associated with a Named User from Airship systems in compliance with data privacy laws.

Uninstalling channels also removes accompanying analytic data (including Performance Analytics) from the system.

See [Individual Data Privacy Rights Under Data Privacy Laws](/docs/guides/audience/privacy/individual-data-privacy/) for more information about data privacy law compliance.

[Jump to examples ↓](#uninstallnameduser-examples)

### `POST /api/named_users/uninstall`

{{< note >}}
Channel uninstallation, like channel creation, is an asynchronous operation and may take some time to complete.
{{< /note >}}

**Security:**

- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Request body**

**Content-Type:** `application/json`

- **`named_user_id`** `array[string]` **REQUIRED**

  Array of strings representing the named_user_id(s) you wish to be uninstalled. Must have between 1 to 100 items in the array with a 128 character/byte maximum per item.

  Min items: 1, Max items: 100

**Responses**

**`200`** All channels have been deleted and disassociated from the Named User.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[OK response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#okresponseobject)

**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`406`** Return when the client requests a version of the API that cannot be satisfied, because no compatible version is currently deployed.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example delete all users and their associated channels*

```http
POST /api/named_users/uninstall HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "named_user_id": ["user-id-1234","user-id-5678"]
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```python
from urbanairship import (
    BasicAuthClient, NamedUser
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

response = NamedUser.uninstall(
    client=client,
    named_users=["user-id-1234", "user-id-5678"]
  )

```

```ruby
require 'urbanairship'

UA = Urbanairship
airship = UA::Client.new(key: '<app key>', secret: '<master secret>')

named_user_uninstall = UA::NamedUserUninstaller.new(client: airship)
named_user_uninstall.named_user_ids = ['user-id-1234']
named_user_uninstall.uninstall

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

NamedUserUninstallRequest namedUserUninstallRequest = NamedUserUninstallRequest
        .newUninstallRequest(ImmutableList.of("user-id-1234","user-id-5678"));

Response<GenericResponse> response = client.execute(namedUserUninstallRequest);

```

---

## Scoped Named User batch operations {#performnameduserscopedbatchoperations}

Supports multiple operations on a Named User within a single request for a specified `scope`. The supported operation is
`subscription_lists`. The behavior of each of these operations are the same as their individual request counterpart.


[Jump to examples ↓](#performnameduserscopedbatchoperations-examples)

### `POST /api/named_users/scoped/{named_user_id}`

{{< note >}}
If you are using a single-channel Preference Center created before October 10, 2022, that has not been [migrated to user-level](/docs/guides/messaging/features/preference-centers/#migrating-to-a-user-level-preference-center), use the [`/api/channels/subscription_lists` endpoint](/docs/developer/rest-api/ua/operations/channels/#modifychannelsubscriptions) to add or remove individual channels to/from your subscription list.

{{< /note >}}

{{< important >}}
The path parameter `named_user_id` should be URL-encoded to ensure it is handled correctly.
Requirements of `named_user_id` can be found [here](#operation-api-named_users-associate-post-associate-channel_id-with-named-user-named_user_id).

{{< /important >}}

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `named_user_id` | `string` | Required | A string value identifying the user, without leading or trailing whitespace. If this value contains reserved or special characters they must be URL encoded.  |

**Request body**

**Content-Type:** `application/json`

- **`scoped`** `array` <[Named User scoped batch item]({{< ref "/developer/rest-api/ua/schemas/subscription-lists/" >}}#scopedbatchitem)>

  An array of scopes and subscription lists.

**Responses**

**`200`** The scoped Named User batch operations succeeded.

Response body:

**Content-Type:** `application/vnd.urbanairship+json; version=3`

[OK response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#okresponseobject)

**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`401`** Authentication information (the app key and secret or bearer token) was either incorrect or missing.

Response body:

**Content-Type:** `text/plain`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`403`** Authentication was correct, but the user does not have permission to access the requested API, e.g., if the feature in question is not included in your pricing plan.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**`406`** Return when the client requests a version of the API that cannot be satisfied, because no compatible version is currently deployed.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example scoped Named User batch operations
*

```http
POST /api/named_users/scoped/b8f9b663-0a3b-cf45-587a-be880946e881 HTTP/1.1
Authorization: Basic <application or master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "scoped": [
      {
          "scope": ["app"],
          "subscription_lists": {
              "subscribe": ["stickers", "gifs"],
              "unsubscribe": ["cookies"]
          }
      },
      {
          "scope": ["web"],
          "subscription_lists": {
              "subscribe": ["daily_snacks", "brunch"],
              "unsubscribe": ["promotions"]
          }
      }
   ]
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

Set<NamedUserScopeType> scopeTypes1 = new HashSet<>(Arrays.asList(NamedUserScopeType.APP));
Set<String> subscribeLists1 = new HashSet<>(Arrays.asList("stickers", "gifs"));
Set<String> unsubscribeLists1 = new HashSet<>(Arrays.asList("cookies"));

Set<NamedUserScopeType> scopeTypes2 = new HashSet<>(Arrays.asList(NamedUserScopeType.WEB));
Set<String> subscribeLists2 = new HashSet<>(Arrays.asList("daily_snacks", "brunch"));
Set<String> unsubscribeLists2 = new HashSet<>(Arrays.asList("promotions"));

NamedUserScope namedUserScope1 = NamedUserScope.newBuilder()
        .setScopes(scopeTypes1)
        .setSubscribeLists(subscribeLists1)
        .setUnsubscribeLists(unsubscribeLists1)
        .build();

NamedUserScope namedUserScope2 = NamedUserScope.newBuilder()
        .setScopes(scopeTypes2)
        .setSubscribeLists(subscribeLists2)
        .setUnsubscribeLists(unsubscribeLists2)
        .build();

NamedUserScopedPayload namedUserScopedPayload = NamedUserScopedPayload.newBuilder()
        .addNamedUserScope(namedUserScope1)
        .addNamedUserScope(namedUserScope2)
        .build();

NamedUserScopedRequest request = NamedUserScopedRequest.newRequest("named_user_id", namedUserScopedPayload);
Response<GenericResponse> response = client.execute(request);

```

---

## Set or remove attributes on Named Users {#modifynameduserattributes}

Set or remove attributes on a Named User.

A single request body may contain a `set` or `remove` field, or both, or a single `set` field. If both `set` and `remove` fields are present and the intersection of the attributes in these fields is not empty, then a `400` will be returned.

If an attribute request is partially valid, i.e., at least one attribute exists, Airship returns a `200` with a warning about the attributes that failed to update.
The attributes listed in the `warnings` string will be in CSV format.


[Jump to examples ↓](#modifynameduserattributes-examples)

### `POST /api/named_users/{named_user_id}/attributes`

{{< note >}}
Airship returns a `200` with a warning if you attempt to set attributes on a Named User that does not exist.

{{< /note >}}

{{< tip >}}
If you wish to set attributes on multiple Named Users at once, we recommend
using [/api/channels/attributes](/docs/developer/rest-api/ua/operations/channels/#modifychannelattributes) which
supports an `audience` object in the request body.

{{< /tip >}}

**Security:**

- [basicAppAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAppAuth)
- [basicAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-basicAuth)
- [bearerAuth]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-bearerAuth)
- [oauth2Token]({{< ref "/developer/rest-api/ua/introduction/" >}}#security-oauth2Token): nu

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `named_user_id` | `string` | Required | The Named User you are setting the attributes for. |

**Request body**

**Content-Type:** `application/json`

Type: `array`

**Responses**

**`200`** Success. If an attribute request is partially valid, i.e., at least one attribute exists,
Airship returns a `200` with a warning string containing a CSV list of attributes that failed to update. Airship also returns a `200` with a warning if you attempt to set attributes on a `named_user`, even if the `named_user` does not exist.


Response body:

**Content-Type:** `application/json`

- **`ok`** `boolean`

  Set to `true` when status code is `200`.


- **`warnings`** `string`

  Warnings encountered when updating Named User attributes.


**`400`** There was a parsing or validation error in the request. Bad Request errors typically include `path` and `location` in the response to help you find the cause of the error.

Response body:

**Content-Type:** `application/json`

[Error response]({{< ref "/developer/rest-api/ua/schemas/responses/" >}}#error)

**Examples**

*Example*

```http
POST /api/named_users/my_named_user/attributes HTTP/1.1
Authorization: Basic <master authorization string>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "attributes": [
        {
            "action": "set",
            "key": "firstName",
            "value": "Gyuri",
            "timestamp": "2020-09-19 12:00:00"
        },
        {
            "action": "remove",
            "key": "birthDate",
            "timestamp": "2020-09-19 12:00:00"
        },
        {
            "action": "set",
            "key": "lastName",
            "value": "Pataki",
            "timestamp": "2020-09-19 12:00:00"
        }
    ]
}

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3

{
   "ok": true
}

```

```python
from urbanairship import (
    BasicAuthClient, Attribute, ModifyAttributes
)

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)

set_major_league = Attribute(
                      action="set",
                      key="major_league",
                      value="sf_giants")

remove_minor_league = Attribute(
                         action="remove",
                         key="minor_league")

set_position = Attribute(
                  action="set",
                  key="position",
                  value="LF")

modifications = ModifyAttributes(
                   airship=client,
                   attributes=[set_major_league,
                               remove_minor_league,
                               set_position],
                   named_user="my_named_user"
                )

modifications.send()

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();

Attribute firstName = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("firstName")
        .setValue("Gyuri")
        .setTimeStamp(DateTime.parse("2020-09-19T12:00:00Z"))
        .build();

Attribute birthDate = Attribute.newBuilder()
        .setAction(AttributeAction.REMOVE)
        .setKey("birthDate")
        .setTimeStamp(DateTime.parse("2020-09-19T12:00:00Z"))
        .build();

Attribute lastName = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("lastName")
        .setValue("Pataki")
        .setTimeStamp(DateTime.parse("2020-09-19T12:00:00Z"))
        .build();

NamedUserAttributePayload payload = NamedUserAttributePayload.newBuilder()
        .addAttribute(firstName)
        .addAttribute(birthDate)
        .addAttribute(lastName)
        .build();

NamedUserAttributeRequest request = NamedUserAttributeRequest.newRequest("my_named_user", payload);
Response<NamedUserAttributeResponse> response = client.execute(request);

```

---

