# Channels

Channels are Airship's unique identifiers for addressing applications on iOS, Android, Fire OS, and web devices.


## Channel listing {#getchannels}

List all channels registered to this app key, along with associated data and metadata.

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

### `GET /api/channels`

{{< note >}}
Tags added to a channel via the [Named Users tag endpoint](/docs/developer/rest-api/ua/operations/tags/#modifynamedusertags) will not appear with a request to this endpoint. To view those tags, you must [look up the Named User](/docs/developer/rest-api/ua/operations/named-users/#getnameduser) associated with the channel.

{{< /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): chn

**Query parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `limit` | `integer` |  | The default limit is 1,000 channel objects returned per request. Set the limit to 1,000 or fewer in your API calls. Max: 1000 |

**Responses**

**`200`** Returns OK for success with the JSON response. Tags added to a channel using `/named_users/tags` are not returned from this endpoint. To view those tags, you must look up the Named User associated with the channel.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `Link` | `string` | Provides the URL to the current page of results. The query within the URL contains the `limit` (the number of results on the page) and `start` (the first `channel_id` in the result set) parameters. |

Response body:

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

- **`channels`** `array` <[Channel listing object]({{< ref "/developer/rest-api/ua/schemas/channels/" >}}#channellistingobject)>

  An array of channel objects.

- **`next_page`** `string`

  If there is more than one page of results, use this link to get the next page of results.

  Format: `url`

  Example: `https://go.urbanairship.com/api/channels?limit=1000&start=535ec31e-4b07-4b26-bead-a1c0e94e133c`

- **`ok`** `boolean`

  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*

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

```

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

{
   "ok": true,
   "next_page": "https://go.urbanairship.com/api/channels?start=07AAFE44CD82C2F4E3FBAB8962A95B95F90A54857FB8532A155DE3510B481C13&limit=2",
   "channels": [
      {
         "channel_id": "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "device_type": "android",
         "push_address": "FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
         "opt_in": true,
         "installed": true,
         "background": true,
         "created": "2020-03-06T18:52:59",
         "last_registration": "2020-10-07T21:28:35",
         "named_user_id": "some_id_that_maps_to_your_systems",
         "alias": "null",
         "tags": [
            "tag1",
            "tag2"
         ],
         "tag_groups": {
            "tag_group_1": ["tag1", "tag2"],
            "tag_group_2": ["tag1", "tag2"]
         },
         "device_attributes": {
             "ua_device_os": "10",
             "ua_country": "US",
             "ua_device_model": "SM-G973U",
             "ua_local_tz": "America/Los_Angeles",
             "ua_app_version": "2020-02-01T002322-goat",
             "ua_location_settings": "true",
             "ua_language": "en",
             "ua_sdk_version": "12.2.0",
             "ua_carrier": "Verizon "
          },
          "attributes": {
             "first_name": "Cool",
             "last_name": "Person",
             "birthdate": "1983-03-15T00:00:00",
          }
      },
      {
         "channel_id": "bd36e8c7-5a73-47c0-9716-99fd3d4197d5",
         "device_type": "ios",
         "push_address": null,
         "opt_in": false,
         "installed": true,
         "background": true,
         "created": "2020-03-06T18:52:59",
         "last_registration": "2020-10-07T21:28:35",
         "named_user_id": "some_id_that_maps_to_your_systems",
         "alias": "null",
         "tags": [
            "tag1",
            "tag2"
         ],
         "tag_groups": {
            "tag_group_1": ["tag1", "tag2"],
            "tag_group_2": ["tag1", "tag2"]
         },
         "ios": {
            "badge": 0,
            "quiettime": {
               "start": null,
               "end": null
            },
            "tz": null
         }
      }
   ]
}

```

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

ChannelRequest request = ChannelRequest.newRequest();
Response<ChannelResponse> response = client.execute(request);
ChannelView channels = response.getBody().get().getChannelView().get();

```

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

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

for channel in ChannelList(client):
    channel_id = channel.channel_id
    print(channel.channel_id, channel.device_type, channel.tags,
          channel.push_address, channel.named_user_id, channel.opt_in)

```

```ruby
require 'urbanairship'

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

channel_list = UA::ChannelList.new(client: airship)
channel_list.each do |channel|
    puts(channel)
end
puts(channel_list.count)

```

---

## Channel lookup {#getchannel}

Fetch an individual channel registered to the app key, along with associated data and metadata.

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

### `GET /api/channels/{channel_id}`

{{< note >}}
Tags added to a channel via the [Named Users tag endpoint](/docs/developer/rest-api/ua/operations/tags/#modifynamedusertags) will not appear with a request to this endpoint. To view those tags, you must [look up the Named User](/docs/developer/rest-api/ua/operations/named-users/#getnameduser) associated with the channel.

{{< /note >}}

**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): chn

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel_id` | `string` | Required | The unique channel identifier. |

**Responses**

**`200`** Tags added to a channel using `/named_users/tags` are not returned from this endpoint. To view those tags, you must look up the Named User associated with the channel.

Response body:

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

- **`channel`** `object`

  A channel object.

  **One of:**

  - [Channel listing object]({{< ref "/developer/rest-api/ua/schemas/channels/" >}}#channellistingobject)

    Describes a channel listing object.

  - **Open channel object** `object`

    Describes an open channel.

    - **`address`** `string`

      The address to send push notifications to when `device_type` is `email` or `open`.

      Example: `email@example.com`

    - **`channel_id`** `string`

      The unique channel identifier for a device.

      Format: `uuid`

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

    - **`created`** `string`

      The creation [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) of this channel.

      Format: `date-time`

      Read only: true

    - **`last_registration`** `string`

      The last registration [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) of this channel, if known.

      Format: `date-time`

      Nullable: true

      Read only: true

    - **`locale_country`** `string`

      The two-letter country locale short code. Will set the `ua_locale_country` tag group to the specified value.

    - **`locale_language`** `string`

      The two-letter language locale short code. Will set the `ua_locale_language` tag group to the specified value.

    - **`named_user_id`** `string`

      A customer-chosen ID that represents the device user, e.g., CRM ID. This ID cannot have leading or trailing whitespace.

      Min length: 1, Max length: 128

      Example: `john_doe`

      Nullable: true

    - **`open`** `object`

      Contains options that apply when the `device_type` is set to `open`.

      **OBJECT PROPERTIES**

      - **`identifiers`** `object`

        A set of up to 100 key:value pairs representing identifiers for this channel in your own delivery systems and delivered as a part of webhook payloads.

        Example: `[object Object]`

      - **`old_address`** `string`

        If a channel exists for the value of `old_address`, replaces that channel's address with the value of `address`. Use infrequently, such as when an end user's phone number or email address permanently changes.

      - **`open_platform_name`** `string`

        The name of the open channel that this `channel_id` is registered on.

        Example: `Slack`

    - **`opt_in`** `boolean`

      If true, the channel is opted in to push notifications. If false, it is not.

    - **`set_tags`** `boolean`

      When `true`, replaces all device tags on the channel with the set provided in `"tags"`. When `false` or absent, the `"tags"` set is unioned with existing device tags.

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

      One or more tag group objects (including [Device Property Tags](/docs/reference/device-property-tags/)) associated with this channel.

      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.

    - **`tags`** `array[string]`

      An array of tags associated with this channel.

      Min items: 0, Max items: 1000

      Example: `Federer fan,Messi fan`

    - **`timezone`** `string`

      An IANA tzdata identifier for the time zone as a string, e.g., `"America/Los_Angeles"`. Will set the `timezone` tag group tag with the specified value.

    - **`type`** `string`

      Specifies the device platform for a channel.

      Possible values: `open`


- **`ok`** `boolean`

  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*

```http
GET /api/channels/9c36e8c7-5a73-47c0-9716-99fd3d4197d5 HTTP/1.1
Authorization: Basic <application authorization string>
Accept: application/vnd.urbanairship+json; version=3

```

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

{
   "ok": true,
   "channel": {
      "channel_id": "9c36e8c7-5a73-47c0-9716-99fd3d4197d5",
      "device_type": "ios",
      "installed": true,
      "opt_in": false,
      "background": true,
      "push_address": "FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660",
      "created": "2020-08-08T20:41:06",
      "last_registration": "2020-05-01T18:00:27",
      "named_user_id": "some_id_that_maps_to_your_systems",
      "alias": null,
      "tags": [
         "tag1",
         "tag2"
      ],
      "tag_groups": {
         "tag_group_1": ["tag1", "tag2"],
         "tag_group_2": ["tag1", "tag2"]
      },
      "ios": {
         "badge": 0,
         "quiettime": {
            "start": null,
            "end": null
         },
         "tz": "America/Los_Angeles"
      },
      "open_tracking_opted_in": "2022-11-26T00:00:00",
      "open_tracking_opted_out": "2022-12-11T00:00:00",
      "click_tracking_opted_in": "2022-11-26T00:00:00",
      "click_tracking_opted_out": "2022-12-11T00:00:00"
   }
}

```

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

ChannelRequest request = ChannelRequest.newRequest("9c36e8c7-5a73-47c0-9716-99fd3d4197d5");
Response<ChannelResponse> response = client.execute(request);
ChannelView channel = response.getBody().get().getChannelView().get();

```

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

client = BasicAuthClient(
    key='<app_key>',
    secret='<master_secret>'
)
channel = ChannelInfo(client).lookup('9c36e8c7-5a73-47c0-9716-99fd3d4197d5')
print(channel.channel_id, channel.device_type, channel.tags,
      channel.push_address, channel.named_user_id, channel.opt_in)

```

```ruby
require 'urbanairship'

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

channel_client = UA::ChannelInfo.new(client: airship)
channel_info = channel_client.lookup(uuid: '9c36e8c7-5a73-47c0-9716-99fd3d4197d5')
puts(channel_info)

```

*Example open channel lookup response with all optional keys*

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

{
   "ok": true,
   "channel": {
      "channel_id": "b8f9b663-0a3b-cf45-587a-be880946e881",
      "type": "open",
      "opt_in": true,
      "address": "example@example.com",

      "created": "2013-08-08T20:41:06",
      "last_registration": "2014-05-01T18:00:27",

      "named_user_id": "john_doe_123",
      "tags": ["asdf"],

      "tag_groups": {
         "timezone" : ["America/Los_Angeles"],
         "locale_country" : ["US"],
         "locale_language" : ["en"],
         "tag_group_1" : ["tag1", "tag2"],
         "tag_group_2" : ["tag1", "tag2"]
      },

      "open" {
         "open_platform_name": "email",
         "identifiers": {
            "com.example.external_id": "df6a6b50-9843-7894-1235-12aed4489489"
         }
      }
   }
}

```

*Example open channel lookup response with only required keys*

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

{
   "ok": true,
   "channel": {
      "channel_id": "b8f9b663-0a3b-cf45-587a-be880946e881",

      "type": "open",
      "opt_in": false,
      "address": "example@example.com",

      "created": "2013-08-08T20:41:06",
      "last_modified": "2014-05-01T18:00:27",

      "tags": [],
      "tag_groups" {},

      "open": {
         "open_platform_name": "email"
      }
   }
}

```

---

## Channel tags {#modifychanneltags}

Add, remove, or set tags on a channel.

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

### `POST /api/channels/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 channel. Adding more than 1,000 tags per channel 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 channel, 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): chn

**Request body**

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

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

  Adds the specified tags to the channel. Tags that are already present are not modified/removed as a result of this operation.

  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**

  Specifies one or more channels that you want to apply tag operations to.

  **OBJECT PROPERTIES**

  - **`amazon_channel`** `array[string]`

    The unique channel identifier for a Fire OS device.

    Min items: 1, Max items: 1000

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

  - **`android_channel`** `array[string]`

    The unique channel identifier for an Android device.

    Min items: 1, Max items: 1000

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

  - **`channel`** `array[string]`

    The unique channel identifier for `email`, `sms`, `open`, or `web` device types.

    Min items: 1, Max items: 1000

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

  - **`ios_channel`** `array[string]`

    The unique channel identifier for an iOS device.

    Min items: 1, Max items: 1000

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

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

  Removes the specified tags from the channel.

  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)>

  Assigns a list of tags exactly. Any previously set tags that are not in this current list will be 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`** Returns OK for success. If a tag request is partially valid, i.e., at least one tag group exists and is active, a 200 is 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/vnd.urbanairship+json; version=3`

- **`ok`** `boolean`

  If true, your request was processed normally.

- **`warnings`** `array[string]`

  Returned when some tag groups could not be updated. Contains a string indicating each tag group that could not be updated and the reason the update failed.

**`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)

**Examples**

*Example*

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

{
   "audience": {
      "ios_channel": "b8f9b663-0a3b-cf45-587a-be880946e881",
      "android_channel": "13863b3c-f860-4bbf-a9f1-4d785379b8a2"
   },
   "add": {
      "my_fav_tag_group1": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group2": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group3": ["tag1", "tag2", "tag3"]
   }
}

```

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

{
   "ok": true,
   "warnings": ["The following tag groups do not exist: my_fav_tag_group2", "The following tag groups are deactivated: my_fav_tag_group3"]
}

```

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

ChannelTagRequest request = ChannelTagRequest.newRequest()
        .addIOSChannel("b8f9b663-0a3b-cf45-587a-be880946e881")
        .addAndroidChannel("13863b3c-f860-4bbf-a9f1-4d785379b8a2")
        .addTags("my_fav_tag_group1", ImmutableSet.of("tag1", "tag2", "tag3"))
        .addTags("my_fav_tag_group2", ImmutableSet.of("tag1", "tag2", "tag3"))
        .addTags("my_fav_tag_group3", ImmutableSet.of("tag1", "tag2", "tag3"));

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

```

```python
import urbanairship as ua

client = ua.BasicAuthClient('<app key>', '<master secret>')
channel_tags = ua.devices.ChannelTags(client)
ios_audience = ['b8f9b663-0a3b-cf45-587a-be880946e881']
android_audience = ['13863b3c-f860-4bbf-a9f1-4d785379b8a2']
channel_tags.set_audience(ios_audience, android_audience
)
channel_tags.add('my_fav_tag_group1', ['tag1', 'tag2', 'tag3'])
channel_tags.remove('my_fav_tag_group2', 'tag4')
channel_tags.send()

```

```ruby
require 'urbanairship'

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

channel_tags = UA::ChannelTags.new(client: airship)
ios_audience = 'b8f9b663-0a3b-cf45-587a-be880946e881'
android_audience = '13863b3c-f860-4bbf-a9f1-4d785379b8a2'
channel_tags.set_audience(
    ios: ios_audience,
    android: android_audience
)
channel_tags.add(group_name: 'my_fav_tag_group1', tags: ['tag1', 'tag2', 'tag3'])
channel_tags.remove(group_name: 'my_fav_tag_group2', tags: 'tag4')
channel_tags.send_request

```

---

## Set or remove attributes on channels {#modifychannelattributes}

Set or remove attributes on a channel. Aside from Airship's [default attributes](/docs/reference/data-collection/attributes/#default-attributes), you must [define attributes in the Airship dashboard](/docs/guides/audience/attributes/adding/) before you can set them on channels.


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

### `POST /api/channels/attributes`

{{< important >}}
Use the [Named Users endpoint](/docs/developer/rest-api/ua/operations/named-users/#modifynameduserattributes) to set or remove attributes on Named Users.

{{< /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): chn

**Request body**

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

- **`attributes`** `object` <[Attribute assignment]({{< ref "/developer/rest-api/ua/schemas/attributes/" >}}#attributesobject)> **REQUIRED**
- **`audience`** `object` **REQUIRED**

  The channel(s) you want to set or remove attributes for.

  **OBJECT PROPERTIES**

  - **`amazon_channel`** `object`

    The unique channel identifier used to target a Fire OS device.

    **OBJECT PROPERTIES**

    - **`amazon_channel`** `object` **REQUIRED**
      **One of:**

      - `string`
      - `array<string>`

  - **`android_channel`** `object`

    The unique channel identifier used to target an Android device.

    **OBJECT PROPERTIES**

    - **`android_channel`** `object` **REQUIRED**
      **One of:**

      - `string`
      - `array<string>`

  - **`channel`** `object`

    The unique channel identifier used to target an open channel device or web device, i.e., web browser. 

    **OBJECT PROPERTIES**

    - **`channel`** `object` **REQUIRED**
      **One of:**

      - `string`
      - `array<string>`

  - **`email_address`** `array[string]`

    The unique channel identifier used to target an email address.

    Min items: 1, Max items: 100

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

  - **`ios_channel`** `object`

    The unique channel identifier used to target an iOS device.

    **OBJECT PROPERTIES**

    - **`ios_channel`** `object` **REQUIRED**
      **One of:**

      - `string`
      - `array<string>`

  - **`sms_id`** `object`

    Selects a single SMS device. The `msisdn` must be `opted_in` to receive notifications.

    **OBJECT PROPERTIES**

    - **`msisdn`** `string` **REQUIRED**

      The recipient phone number.

      Min length: 1, Max length: 128

    - **`sender`** `string` **REQUIRED**

      The sender that the app is configured to send SMS messages from.

      Min length: 1, Max length: 128

  - **`web_channel`** `array[string]`

    The unique channel identifier used to target a web device.

    Min items: 1, Max items: 100

    Example: `00256e0b-b02f-4f12-a77f-4c3d57078330,f59970d3-3d42-4584-907e-f5c57f5d46a1`

**Responses**

**`200`** The operation was successful.

Response body:

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

- **`ok`** `boolean`

  If true, your request was successful.

- **`warning`** `string`

  Alerts you if your request could not be processed. You may receive a 200 with a warning if you provide a `value` that does not match your attribute type. For example, an attribute that expects a numeric value will allow a value of "25" but fail if you input "twenty-five".


**`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)

**Examples**

*Example*

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

{
    "audience": {
       "android_channel": ["13863b3c-f860-4bbf-a9f1-4d785379b8a2"]
    },
    "attributes": [
       {
             "action": "set",
             "key": "major_league",
             "value": "sf_giants"
       },
       {
             "action": "remove",
             "key": "minor_league"
       },
       {
             "action": "set",
             "key": "position",
             "value": "LF"
       },
       {
             "action": "set",
             "key": "specialData",
             "value": {
                  "timestamp": "1983-03-15 10:00:00",
                  "specialties": [
                    {
                        "specialty": {
                            "name": "golden",
                            "property": "small"
                        }
                    },
                    {
                        "specialty": {
                            "name": "silver",
                            "property": "medium"
                        }
                    }
                ]
            }
       }
    ]
}

```

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

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"
)

specialties_string = "{" + \
                   "    \"timestamp\": \"1983-03-15 10:00:00\"," + \
                   "    \"specialties\": [{" + \
                   "            \"specialty\": {" + \
                   "                \"name\": \"golden\"," + \
                   "                \"property\": \"small\"" + \
                   "            }" + \
                   "        }," + \
                   "        {" + \
                   "            \"specialty\": {" + \
                   "                \"name\": \"silver\"," + \
                   "                \"property\": \"medium\"" + \
                   "            }" + \
                   "        }" + \
                   "    ]" + \
                   "}"
specialties_json = json.loads(specialties_string)
specialties = Attribute(
    action="set",
    key="specialties",
    value=specialties_json
)

modifications = Attribute.ModifyAttributes(
    client=client,
    attributes=[set_major_league,
               remove_minor_league,
               set_position],
    channel="13863b3c-f860-4bbf-a9f1-4d785379b8a2"
)

modifications.send()

```

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

Attribute setMajorLeague = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("major_league")
        .setValue("sf_giants")
        .build();

Attribute removeMinorLeague = Attribute.newBuilder()
        .setAction(AttributeAction.REMOVE)
        .setKey("minor_league")
        .build();

Attribute setPosition = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("position")
        .setValue("LF")
        .build();

String specialtiesStr = "{" +
                        "    \"timestamp\": \"1983-03-15 10:00:00\"," +
                        "    \"specialties\": [{" +
                        "            \"specialty\": {" +
                        "                \"name\": \"golden\"," +
                        "                \"property\": \"small\"" +
                        "            }" +
                        "        }," +
                        "        {" +
                        "            \"specialty\": {" +
                        "                \"name\": \"silver\"," +
                        "                \"property\": \"medium\"" +
                        "            }" +
                        "        }" +
                        "    ]" +
                        "}";
JSONObject specialtiesJson = new JSONObject(specialtiesStr);
Attribute setSpecialties = Attribute.newBuilder()
        .setAction(AttributeAction.SET)
        .setKey("specialties")
        .setValue(specialtiesJson)
        .build();

ChannelAttributesPayload payload = ChannelAttributesPayload.newBuilder()
        .addAttribute(setMajorLeague)
        .addAttribute(removeMinorLeague)
        .addAttribute(setPosition)
        .setAudience(AttributeAudience.newBuilder()
                .addDeviceId(AttributeAudienceType.ANDROID_CHANNEL, "13863b3c-f860-4bbf-a9f1-4d785379b8a2")
                .build())
        .build();

ChannelAttributesRequest request = ChannelAttributesRequest.newRequest(payload);
Response<ChannelAttributesResponse> response = client.execute(request);

```

```ruby
require 'urbanairship'

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

channel_info = UA::ChannelInfo.new(client: airship)
channel_info.audience = {"android_channel": '13863b3c-f860-4bbf-a9f1-4d785379b8a2'}
channel_info.attributes =  {
    "action": "set",
    "key": "major_league",
    "value": "sf_giants"
}
channel_info.set_attributes

```

*Example request with dates and numbers*

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

{
    "audience": {
       "android_channel": ["13863b3c-f860-4bbf-a9f1-4d785379b8a2"]
    },
    "attributes": [
       {
             "action": "set",
             "key": "birthday",
             "value": "1983-03-15 10:00:00"
       },
       {
             "action": "set",
             "key": "fav_number",
             "value": 42
       },
       {
             "action": "remove",
             "key": "another_attribute"
       }
    ]
}

```

---

## Subscribe or unsubscribe channels to/from subscription lists {#modifychannelsubscriptions}

Subscribe or unsubscribe channels to/from Subscription Lists.


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

### `POST /api/channels/subscription_lists`

{{< 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. Otherwise, use the [Scoped Named User batch operations endpoint](/docs/developer/rest-api/ua/operations/named-users/#performnameduserscopedbatchoperations) to do so.

{{< /note >}}

{{< important >}}
You must first [create a subscription list in the dashboard](/docs/guides/audience/segmentation/audience-lists/subscription/#creating-a-list), then you can refer to its ID when subscribing users. When subscribing users, if the list has not already been created in the dashboard, then the list will be created at the same time but will not be accessible from the dashboard; the list will available for API use only.
{{< /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): chn

**Request body**

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

**All of:**

- [Audience selector (max 100)]({{< ref "/developer/rest-api/ua/schemas/audience-selection/" >}}#audienceselector100)

  An audience selector forms the expression that determines the set of channels to target.

- `array`

  An array of Subscription List objects.


**Responses**

**`202`** Returns OK for success.

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)

**Examples**

*Example*

```http
POST /api/channels/subscription_lists HTTP/1.1
Authorization: Basic <App Auth>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "subscription_lists": [
      {
         "action":"subscribe",
         "list_id":"intriguing_ideas"
      },
      {
         "action":"unsubscribe",
         "list_id":"animal_facts"
      }
   ],
   "audience": {
      "ios_channel": [
         "b8f9b663-0a3b-cf45-587a-be880946e881"
      ],
      "email_address": [
         "homer@example.com",
         "nick@example.com"
      ]
   }
}

```

```python
import urbanairship as ua

client = ua.BasicAuthClient('<app key>', '<master secret>')

subscription_list = ua.SubscriptionList(client)

subscription_list.subscribe(list_id="intriguing_ideas",
                            audience=ua.email("nick@example.com")
                           )

subscription_list.unsubscribe(list_id="animal_facts", 
                              audience=ua.ios_channel(
                                 "b8f9b663-0a3b-cf45-587a-be880946e881"
                                 )
                              )

```

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

 SubscriptionList subscriptionList = SubscriptionList.newBuilder()
       .setListId("big_deals")
       .setAction(SubscriptionListAction.SUBSCRIBE)
       .build();

 SubscriptionListPayload payload = SubscriptionListPayload.newBuilder()
       .addSubscriptionList(subscriptionList)
       .setAudience(ChannelAudience.newBuilder()
                .addDeviceId(ChannelAudienceType.ANDROID_CHANNEL, "002b4104-c94f-418d-be86-ead3214b3244").build())
       .build();

 SubscriptionListRequest request  = SubscriptionListRequest.newRequest(payload);
 Response<SubscriptionListResponse> response = client.execute(request);

```

---

## Uninstall channels {#uninstallchannels}

Uninstalls a channel, removing it and all accompanying analytic data (including Performance Analytics) from Airship systems in accordance with data privacy law compliance.

Uninstallation is handled automatically by the Airship SDK and push systems. If a user decides to opt in to communications again (either by using your app or other user preferences), they will create a new channel and a new set of analytic data.
The value of a Channel ID may be the same as before however none of the associated metadata will persist when a user opts in again. A new Channel ID will be created if the user clears their browser’s cookies and data, deletes and reinstalls the app, etc.

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 ↓](#uninstallchannels-examples)

### `POST /api/channels/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): chn

**Request body**

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

Type: `array`

**Responses**

**`202`** Returns OK for success.

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)

**Examples**

*Example*

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

[
   {
      "channel_id": "b8f9b663-0a3b-cf45-587a-be880946e881",
      "device_type": "ios"
   },
   {
      "channel_id": "13863b3c-f860-4bbf-a9f1-4d785379b8a2",
      "device_type": "android"
   }
]

```

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

{
   "ok": true
}

```

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

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

channel_uninstall = ChannelUninstall(client)
channel = {
    "channel_id": 'b8f9b663-0a3b-cf45-587a-be880946e881',
    "device_type": "ios"
}

channel_uninstall.uninstall(channel)

```

```ruby
require 'urbanairship'

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

cu = UA::ChannelUninstall.new(client: airship)

chans = [{"channel_id" => "b8f9b663-0a3b-cf45-587a-be880946e881",
          "device_type" => "ios"},
         {"channel_id" => "13863b3c-f860-4bbf-a9f1-4d785379b8a2",
          "device_type" => "android"}]

cu.uninstall(channels: chans)

```

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

 Set<ChannelUninstallDevice> channels = ImmutableSet.of(
       new ChannelUninstallDevice("00f74677-4616-4958-bd91-30e949814d2c", ChannelUninstallDeviceType.IOS),
       new ChannelUninstallDevice("007f7156-9b82-4cb6-a2f9-e2c8e7fce13d", ChannelUninstallDeviceType.ANDROID)
 );

 ChannelUninstallPayload payload = ChannelUninstallPayload.newBuilder()
       .setChannels(channels)
       .build();

 ChannelUninstallRequest request = ChannelUninstallRequest.newRequest(payload);
 Response<ChannelUninstallResponse> response = client.execute(request);

```

---

