# Email

Register email channels, set opt-in status, and manipulate tags on email channels.


## Create email attachment {#createemailattachment}

Create attachments by `POST`ing to the attachments URI. The body of the request must be a JSON object describing and including the contents of a file to attach.


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

### `POST /api/attachments`

{{< important >}}
* Attachments can be used for `transactional` sends only, not `commercial`.

* Attachments cannot be used in Automations.

* Attachment size is limited to 2.5 MB per attachment, with a 20 MB content size limit on each message, including content body and all attachments.

* Attachment count is limited to 10 per email.

* Sending attachments with malicious content is strictly prohibited. This is enforced in part by blocking file types with .bat and .exe extensions.

* Attachments have a TTL (Time To Live) of 60 days.

{{< /important >}}

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

**Request body**

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

- **`content_type`** `string` **REQUIRED**

  The mimetype of the uploaded file including the charset parameter, if needed. Example: `"text/plain; charset=\"UTF-8\""`


  Max length: 100

- **`data`** `string` **REQUIRED**

  Base64-encoded bytes of the file contents representing a maximum of 2.5 MiB of data when decoded. Padding with `=` chars is optional.


- **`filename`** `string` **REQUIRED**

  The name of the uploaded file (max 255 UTF-8 bytes). Multiple files with the same name are allowed in separate requests.


**Responses**

**`201`** The email attachment was created. The response body will contain the IDs of the created attachments.

Response body:

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

- **`attachment_id`** `array[string]`

  The attachment ID for a newly-created attachment. Reference this ID in the `attachments` list in the [Email overrides](/docs/developer/rest-api/ua/schemas/platform-overrides/#emailoverrideobject).

- **`ok`** `boolean`

  Either `true` or `false`. Represents if the operation completed successfully or not. If false, other properties defined here will not necessarily be present.

**`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`** The application does not have the proper entitlement to create attachments.

Response body:

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

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

**Examples**

*Example create email attachment*

```http
POST /attachments HTTP/1.1
Authorization: Bearer <authorization token>
Content-Type: application/json
Accept: application/vnd.urbanairship+json; version=3

{
  "filename": "rickroll.png",
  "content_type": "text/plain; charset=\"UTF-8\"",
  "data": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8..."
}

```

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

{
    "ok": true,
    "attachment_ids": [
        "b0c46a8d-b701-441b-9d6e-147c183b28ca"
    ]
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();
        
EmailAttachmentRequest emailAttachmentRequest = EmailAttachmentRequest.newRequest()
        .setContentType("text/plain; charset=\"UTF-8\"")
        .setData("iBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8...")
        .setFilename("rickroll.png");

Response<EmailAttachmentResponse> response = client.execute(emailAttachmentRequest);

```

```python
from urbanairship import (
    BearerTokenClient, EmailAttachment
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

attachment = EmailAttachment(
  client=client,
  filename='rickroll.png', 
  content_type='image/png; charset="UTF-8"', 
  filepath='path/to/never_gonna.png'
)
response = attachment.post()

print(response.get('attachment_ids'))

```

---

## Custom unsubscribe email channel {#customunsubscribeemailchannel}

Opts-out an email address using a custom unsubscribe token. Requires [Custom Unsubscribe](/docs/developer/api-integrations/email/custom-unsubscribe-pages/) be enabled for your project.

This endpoint is public and does not require authentication.

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

### `GET /api/channels/email/custom-unsubscribe`

**Query parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `ua_unsubscribe_token` | `string` | Required | The token for the unsubscribe request. |
| `ua_redirect` | `string` |  | URL of the page to redirect to after unsubscribe. A default confirmation page will be used if not provided. |

**Responses**

**`302`** The channel was successfully opted out and will be redirected to a confirmation page.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `Location` | `string` | URL of the page to redirect to after unsubscribe. |

**`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
GET /api/channels/email/custom-unsubscribe?ua_redirect=https://example.com/success.html&ua_unsubscribe_token=eyJhcHBfa2V5IjoiVmwwd3lHOGtTeUN5T1VXOThXajR4ZyIsImNhbXBhaWducyI6W10sInB1c2hfaWQiOiJlY2U0MDliMC0yNzYyLTExZWUtYjE4Ny0wMjQyNDkzZjM2MTkiLCJtZXNzYWdlX3R5cGUiOiJjb21tZXJjaWFsIiwiY2hhbm5lbF9pZCI6Ik9IWWdxTDJfU3FHMTRQZWlfWjV2QkEifQ%3D%3D HTTP/1.1
Accept: */*

```

```http
HTTP/1.1 302 Found
Location: https://example.com/success.html

```

---

## Email tags {#modifyemailchanneltags}

Add, remove, or set tags for a single email channel.

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

### `POST /api/channels/email/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:**

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

A single request body can contain an `add` and/or `remove` field or a single `set` field. One or more of the `add`, `remove`, or `set` keys must be present in the request.

**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 the email address you want to perform tag operations against. Must contain a single `email_address` key.

  **OBJECT PROPERTIES**

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

    The email address you want to modify tags for. Accepts a single string value representing an email address.

    Example: `name@example.com`

- **`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 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`** Returns OK for success. 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/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)

**Examples**

*Example*

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

{
   "audience": {
      "email_address": "name@example.com"
   },
   "add": {
      "my_fav_tag_group1": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group2": ["tag1", "tag2", "tag3"],
      "my_fav_tag_group3": ["tag1", "tag2", "tag3"]
   }
}

```

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

EmailTagRequest request = EmailTagRequest.newRequest();
emailTagRequest.addEmailChannel("name@example.com")
        .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<EmailChannelResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BearerTokenClient, EmailTags
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

# replaces all existing tags on an email channel
email_tags = EmailTags(airship=client,
                          address='name@example.com')
email_tags.set(group='my_tag_group',
              tags=['one', 'two', 'three'])
email_tags.send()

# adds and removes tags from an email channel
email_tags = EmailTags(airship=client,
                          address='name@example.com')
email_tags.remove(group='my_tag_group',
                  tags=['one', 'two', 'three'])
email_tags.add(group='my_tag_group',
              tags=['some', 'new', 'tags'])
email_tags.send()

```

```ruby
require 'urbanairship'

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

email_tags = UA::EmailTags.new(client: airship)
#set an audience
email_tags.set_audience(email_address: 'name@example.com')
#add a tag
email_tags.add(group_name: 'my_fav_tag_group1', tags: 'tag2')
#remove a tag
email_tags.remove(group_name: 'my_fav_tag_group1', tags: 'tag1')
email_tags.send_request

```

---

## Look up an email address {#getemailchannel}

Returns a channel by email address. For security, email addresses are one-way hashed and aren't returned when you look up a channel by ID. Use this endpoint to find a channel belonging to a particular email address.


You may need to escape the `@` character in URLs using`%40`.


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

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

{{< note >}}
Emails with an `opted_out` date that is after or equal to the `opted_in` date will not be sent for that channel.

A `commercial_opted_in` date is required for sending commercial emails. Transactional emails do not require a `transactional_opted_in`. This field is used in the case where a user has unsubscribed to transactional email and would like to reassert consent to receive transactional emails.

The `opt_in` property is always set to true for an email channel, so it should be ignored.
{{< /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

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `email` | `string` | Required | The email address of the channel you want to look up. |

**Responses**

**`200`** A channel exists for the email address

Response body:

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

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

  Describes a channel listing object.

- **`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/email/name%40example.com HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

```

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

{
   "ok": true,
   "channel": {
      "channel_id": "01234567-890a-bcde-f012-3456789abc0",
      "device_type": "email",
      "installed": true,
      "created": "2020-08-08T20:41:06",
      "named_user_id": "some_id_that_maps_to_your_systems",
      "email_address": "name@example.com",
      "tag_groups": {
         "tag_group_1": ["tag1", "tag2"],
         "tag_group_2": ["tag1", "tag2"]
      },
      "address": null,
      "opt_in": true,
      "commercial_opted_in": "2020-10-28T10:34:22",
      "commercial_opted_out": "2020-06-03T09:15:00",
      "transactional_opted_in": "2020-10-28T10:34:22",
      "open_tracking_opted_in": "2022-12-11T00:00:00",
      "click_tracking_opted_in": "2022-12-11T00:00:00",
      "open_tracking_opted_out": "2022-12-12T00:00:00",
      "click_tracking_opted_out": "2022-12-12T00:00:00",
      "last_registration": "2020-05-01T18:00:27"
   }
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();
        
ChannelRequest channelRequest = ChannelRequest.newEmailLookupRequest("name@example.com");
Response<ChannelResponse> response = client.execute(channelRequest);

```

```python
from urbanairship import (
    BearerTokenClient, Email
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

response = Email.lookup(airship=client, address='name@example.com')

```

```ruby
require 'urbanairship'

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

email_channel = UA::Email.new(client: airship)
email_channel.address = 'name@example.com'
email_channel.lookup

```

---

## Register email channel {#registeremailchannel}

Create a new email channel or update an existing channel. If you provide the email address of an existing channel, the call is treated as a PUT.
To update the address of an existing channel, see the [Replace Email Channel](/docs/developer/rest-api/ua/operations/email/#replaceemailchannel) endpoint.

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

### `POST /api/channels/email`

{{< note >}}
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.
{{< /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**

A single email channel object.

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

- **`attributes`** `object`

  An optional object containing the customer-provided attributes associated with the email.

- **`channel`** `object` **REQUIRED**
  **OBJECT PROPERTIES**

  - **`address`** `string` **REQUIRED**

    The email address being registered.

    Example: `name@example.com`

  - **`click_tracking_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted in to click tracking.


    Format: `date-time`

  - **`click_tracking_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted out of click tracking.


    Format: `date-time`

  - **`commercial_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive commercial
emails.


    Format: `date-time`

  - **`commercial_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
commercial emails.


    Format: `date-time`

  - **`locale_country`** `string`

    The device property tag related to locale country setting.

    Example: `US`

  - **`locale_language`** `string`

    The device property tag related to locale language setting.

    Example: `en`

  - **`open_tracking_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted in to open tracking.


    Format: `date-time`

  - **`open_tracking_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted out of open tracking.


    Format: `date-time`

  - **`suppression_state`** `string`

    If an email channel is suppressed, the reason for its suppression. Email
channels with any suppression state set will not have any delivery to
them fulfilled. If a more specific reason is not known, use `imported`.


    Possible values: `spam_complaint`, `commercial_spam_complaint`, `bounce`, `imported`

  - **`timezone`** `string`

    The device property tag related to time zone setting.

    Example: `America/Los_Angeles`

  - **`transactional_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive transactional
emails. Users do not need to opt-in to receive transactional
emails unless they have previously opted out.


    Format: `date-time`

  - **`transactional_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
transactional emails.


    Format: `date-time`

  - **`type`** `string` **REQUIRED**

    The type of channel you are registering.

    Possible values: `email`

    Example: `email`

- **`opt_in_mode`** `string`

  The opt-in mode for registering the channel. `classic` is the default when unspecified, `double` creates a `double_opt_in` event.

  Possible values: `classic`, `double`

  Example: `double`

- **`properties`** `object`

  An object containing event properties. You can use these properties to filter the double opt-in event and reference them in your message content by using handlebars. Items in the `properties` object are limited to a 255-character maximum string length.

  Example: `[object Object]`

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

  Optionally one or more tag group objects associated with the email.

  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`** An existing email channel was found matching the address and was
updated.


Response body:

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

- **`attributes`** `object`
  **OBJECT PROPERTIES**

  - **`ok`** `boolean`

    If `true`, the attributes were set correctly.

- **`channel_id`** `string`

  A unique string identifying the email channel.

  Format: `uuid`

  Example: `ef625038-70a3-41f1-826f-57bc11dd625a`

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

  If `true`, the operation was successful. If `false`, other properties defined here will not necessarily be present.

- **`tags`** `object`
  **OBJECT PROPERTIES**

  - **`ok`** `boolean`

    If `true`, the tags were set correctly.

**`201`** The email channel was created.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `Location` | `string` | The newly created email channel. |

Response body:

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

- **`channel_id`** `string`

  A unique string identifying the email channel.

  Format: `uuid`

  Example: `ef625038-70a3-41f1-826f-57bc11dd625a`

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

  Either `true` or `false`. Represents if the operation completed successfully or not. If false, other properties defined here will not necessarily be present.

**`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/email HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

 {
    "channel" : {
        "type": "email",
        "commercial_opted_in": "2020-10-28T10:34:22",
        "open_tracking_opted_in": "2022-12-11T00:00:00",
        "click_tracking_opted_in": "2022-12-11T00:00:00",
        "address": "name@example.com",
        "timezone" : "America/Los_Angeles",
        "locale_country" : "US",
        "locale_language" : "en"
    },
    "opt_in_mode" : "classic",
    "properties" : {
        "interests" : "newsletter"
    },
    "tag_operations": {
      "add": {
        "my_fav_tag_group1": ["tag1", "tag2", "tag3"],
        "my_fav_tag_group2": ["tag1", "tag2", "tag3"],
        "my_fav_tag_group3": ["tag1", "tag2", "tag3"]
      }
    },
    "attributes": {
        "my_fav_attribute1": "attribute1",
        "my_fav_attribute2": "attribute2"
    }
 }

```

```http
HTTP/1.1 201 Created
Location: https://go.urbanairship.com/api/channels/251d3318-b3cb-4e9f-876a-ea3bfa6e47bd
Content-Type: application/json

{
    "ok": true,
    "channel_id": "251d3318-b3cb-4e9f-876a-ea3bfa6e47bd",
    "attributes": {"ok": true},
    "tags": {"ok": true}
}

```

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

RegisterEmailChannel emailChannel = RegisterEmailChannel.newBuilder()
        .setAddress("name@example.com")
        .setEmailOptInLevel(OptInLevel.EMAIL_COMMERCIAL_OPTED_IN, "2020-10-28T10:34:22")
        .setEmailOptInMode(OptInMode.CLASSIC)
        .addProperty("interests","newletter")
        .build();

RegisterEmailChannelRequest request = RegisterEmailChannelRequest.newRequest(emailChannel);
Response<EmailChannelResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BearerTokenClient, Email
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

email = Email(
    client=client,
    address='name@example.com',
    commercial_opted_in='2020-10-28T10:34:22',
    timezone='America/Los_Angeles',
    locale_country='US',
    locale_language='en'
)
response = email.register()

```

```ruby
require 'urbanairship'

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

email_channel = UA::Email.new(client: airship)
email_channel.type = 'email'
email_channel.commercial_opted_in = '2020-10-28T10:34:22'
email_channel.address = 'name@example.com'
email_channel.timezone = 'America/Los_Angeles'
email_channel.locale_country = 'US'
email_channel.locale_language = 'en'
email_channel.register

```

---

## Remove suppression from an email channel {#unsuppressemailchannel}

Remove the suppression reason for an existing email channel, allowing the channel to receive emails, depending on the channel's commercial and transactional opt-in status.


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

### `POST /api/channels/email/unsuppress`

{{< important >}}
Calling this endpoint will not modify commercial or transactional opt-in status to opted-in.
{{< /important >}}

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

- **`address`** `string` **REQUIRED**

  The email address for the channel to be unsuppressed.

  Example: `user@example.com`

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

**`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
POST /api/channels/email/unsuppress HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "address": "name@example.com"
}

```

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

{
    "ok": true
}

```

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

UnsuppressEmailChannelRequest request = UnsuppressEmailChannelRequest.newRequest("name@example.com");
Response<GenericResponse> response = client.execute(request);

```

---

## Replace email channel {#replaceemailchannel}

Creates a new email channel in place of the provided channel. You may
use this endpoint to change a contact's email address. When called with
an email channel, this endpoint will:

* Register a new channel
* Associate the new email channel with the same user as the source channel
* Uninstall the source channel

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

### `POST /api/channels/email/replace/{channel_id}`

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

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `channel_id` | `string` | Required | The email `channel_id` you want to modify. |

**Request body**

A single email channel object.

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

- **`attributes`** `object`

  An optional object containing the customer-provided attributes associated with the email.

- **`channel`** `object` **REQUIRED**
  **OBJECT PROPERTIES**

  - **`address`** `string` **REQUIRED**

    The email address being registered.

    Example: `name@example.com`

  - **`click_tracking_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted in to click tracking.


    Format: `date-time`

  - **`click_tracking_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted out of click tracking.


    Format: `date-time`

  - **`commercial_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive commercial
emails.


    Format: `date-time`

  - **`commercial_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
commercial emails.


    Format: `date-time`

  - **`locale_country`** `string`

    The device property tag related to locale country setting.

    Example: `US`

  - **`locale_language`** `string`

    The device property tag related to locale language setting.

    Example: `en`

  - **`open_tracking_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted in to open tracking.


    Format: `date-time`

  - **`open_tracking_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user opted out of open tracking.


    Format: `date-time`

  - **`suppression_state`** `string`

    If an email channel is suppressed, the reason for its suppression. Email
channels with any suppression state set will not have any delivery to
them fulfilled. If a more specific reason is not known, use `imported`.


    Possible values: `spam_complaint`, `commercial_spam_complaint`, `bounce`, `imported`

  - **`timezone`** `string`

    The device property tag related to time zone setting.

    Example: `America/Los_Angeles`

  - **`transactional_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive transactional
emails. Users do not need to opt-in to receive transactional
emails unless they have previously opted out.


    Format: `date-time`

  - **`transactional_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
transactional emails.


    Format: `date-time`

  - **`type`** `string` **REQUIRED**

    The type of channel you are registering.

    Possible values: `email`

    Example: `email`

- **`opt_in_mode`** `string`

  The opt-in mode for registering the channel. `classic` is the default when unspecified, `double` creates a `double_opt_in` event.

  Possible values: `classic`, `double`

  Example: `double`

- **`properties`** `object`

  An object containing event properties. You can use these properties to filter the double opt-in event and reference them in your message content by using handlebars. Items in the `properties` object are limited to a 255-character maximum string length.

  Example: `[object Object]`

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

  Optionally one or more tag group objects associated with the email.

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

**`201`** The operation was successful.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `Location` | `string` | The newly created email channel. |

Response body:

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

- **`channel_id`** `string`

  A unique string identifying the email channel.

  Format: `uuid`

  Example: `ef625038-70a3-41f1-826f-57bc11dd625a`

- **`ok`** `boolean`

  Either `true` or `false`. Represents if the operation completed successfully or not. If false, other properties defined here will not necessarily be present.

**`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/email/replace/9c36e8c7-5a73-47c0-9716-99fd3d4197d5 HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
   "channel" : {
      "type": "email",
      "commercial_opted_in": "2022-02-13T11:58:59",
      "address": "name@example.com",
      "timezone" : "America/Los_Angeles",
      "locale_country" : "US",
      "locale_language" : "en"
   }
}

```

```http
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://go.urbanairship.com/api/channels/251d3318-b3cb-4e9f-876a-ea3bfa6e47bd

{
    "ok": true,
    "channel_id": "251d3318-b3cb-4e9f-876a-ea3bfa6e47bd"
}

```

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

RegisterEmailChannel emailChannel = RegisterEmailChannel.newBuilder()
        .setAddress("name@example.com")
        .setEmailOptInLevel(OptInLevel.EMAIL_COMMERCIAL_OPTED_IN, "2022-02-13T11:58:59")
        .setTimeZone("America/Los_Angeles")
        .setLocaleCountry("US")
        .setLocaleLanguage("en")
        .build();

ReplaceEmailChannelRequest request = ReplaceEmailChannelRequest.newRequest("9c36e8c7-5a73-47c0-9716-99fd3d4197d5", emailChannel);
Response<EmailChannelResponse> response = client.execute(request);

```

```ruby
require 'urbanairship'

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

email_channel = UA::Email.new(client: airship)
email_channel.channel_id = '251d3318-b3cb-4e9f-876a-ea3bfa6e47bd'
email_channel.address = 'tommy@example.com'
email_channel.type = 'email'
email_channel.commercial_opted_in = '2020-10-28T10:34:22'
email_channel.replace

```

---

## Suppress an email channel {#suppressemailchannel}

Suppress an existing email channel, disallowing any future delivery from being fulfilled for the channel.


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

### `POST /api/channels/email/suppress`

{{< note >}}
Suppression state types that only apply to commercial messages, such as `commercial_spam_complaint`, cannot overwrite suppression state types that also apply to transactional messages.
{{< /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`

- **`address`** `string` **REQUIRED**

  The email address for the channel to be suppressed.

  Example: `user@example.com`

- **`reason`** `string` **REQUIRED**

  The reason for suppressing the channel. If there is no specific reason, use `imported`.

  Possible values: `spam_complaint`, `commercial_spam_complaint`, `bounce`, `imported`

  Example: `spam_complaint`

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

**`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
POST /api/channels/email/suppress HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "address": "name@example.com",
    "reason": "spam_complaint"
}

```

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

{
    "ok": true
}

```

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

SuppressEmailChannelRequest request = SuppressEmailChannelRequest.newRequest("name@example.com","reason");
Response<GenericResponse> response = client.execute(request);

```

---

## Uninstall email channel {#uninstallemailchannel}

**Removes an email address from Airship. Use with caution.** If the uninstalled email address opts-in again, it might generate a new channel_id. If a user generates a new `channel_id` when they opt-in again, the new `channel_id` cannot be reassociated with any opt-in information, tags, Named Users, Performance Analytics reports, or other information from the that belonged to the previously-uninstalled email channel.

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

### `POST /api/channels/email/uninstall`

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

An email address of the channel to uninstall.

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

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

  The email address of the channel to uninstall.

  Example: `name@example.com`

**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/email/uninstall HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

{
    "email_address": "name@example.com"
}

```

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

{
    "ok": true
}

```

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

UninstallEmailChannel uninstallEmailChannel = UninstallEmailChannel.newBuilder()
        .setEmailAddress("name@example.com")
        .build();

UninstallEmailChannelRequest request = UninstallEmailChannelRequest.newRequest(uninstallEmailChannel);
Response<EmailChannelResponse> response = client.execute(request);

```

```python
from urbanairship import (
    BearerTokenClient, Email
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)
email = Email(airship=client,
                address='name@example.com')
resp = email.uninstall()

```

```ruby
require 'urbanairship'

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

email_channel = UA::Email.new(client: airship)
email_channel.address = 'name@example.com'
email_channel.uninstall

```

---

## Update an email channel {#updateemailchannel}

Update an email channel. You can use this endpoint to update the subscription/unsubscription values.


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

### `PUT /api/channels/email/{email}`

{{< important >}}
If you provide an `address` in this request, it must be the one that is associated with the channel you are updating. You may not update the user's email address with this endpoint.
{{< /important >}}

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

**Path parameters:**

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `email` | `string` | Required | The email `channel_id` you want to modify. |

**Request body**

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

- **`channel`** `object` **REQUIRED**
  **OBJECT PROPERTIES**

  - **`address`** `string`

    The email address associated with the email channel. If provided, it must match the existing email address or the request will be rejected with a 400 status code.

    Example: `tommy@example.com`

  - **`commercial_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive commercial
emails.


    Format: `date-time`

  - **`commercial_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
commercial emails.


    Format: `date-time`

  - **`device_type`** `string`

    The type of channel you are updating.

    Possible values: `email`

    Example: `email`

  - **`locale_country`** `string`

    The device property tag related to locale country setting.

    Example: `US`

  - **`locale_language`** `string`

    The device property tag related to locale language setting.

    Example: `en`

  - **`suppression_state`** `string`

    If an email channel is suppressed, the reason for its suppression. Email
channels with any suppression state set will not have any delivery to
them fulfilled. If a more specific reason is not known, use `imported`.


    Possible values: `spam_complaint`, `commercial_spam_complaint`, `bounce`, `imported`

  - **`timezone`** `string`

    The device property tag related to time zone setting.

    Example: `America/Los_Angeles`

  - **`transactional_opted_in`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user gave explicit permission to receive transactional
emails. Users do not need to opt-in to receive transactional
emails unless they have previously opted out.


    Format: `date-time`

  - **`transactional_opted_out`** `string`

    The [date-time](/docs/developer/rest-api/ua/introduction/#date-time-format) when a user explicitly denied permission to receive
transactional emails.


    Format: `date-time`

**Responses**

**`200`** The email channel was updated.

Response headers:

| Name | Type | Description |
|------|------|-------------|
| `Location` | `string` | The updated email channel. |

Response body:

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

- **`channel_id`** `string`

  A unique string identifying the email channel.

  Format: `uuid`

  Example: `ef625038-70a3-41f1-826f-57bc11dd625a`

- **`ok`** `boolean`

  Either `true` or `false`. Represents if the operation completed successfully or not. If false, other properties defined here will not necessarily be present.

**`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 update email address*

```http
PUT /api/channels/email/251d3318-b3cb-4e9f-876a-ea3bfa6e47bd HTTP/1.1
Authorization: Bearer <authorization token>
Accept: application/vnd.urbanairship+json; version=3
Content-Type: application/json

 {
     "channel" : {
        "device_type": "email",
        "address": "tommy@example.com",
        "commercial_opted_in": "2020-10-28T10:34:22"
     }
  }

```

```http
HTTP/1.1 200 OK
Content-Type: application/vnd.urbanairship+json; version=3
Location: https://go.urbanairship.com/api/channels/251d3318-b3cb-4e9f-876a-ea3bfa6e47bd

{
    "ok": true,
    "channel_id": "251d3318-b3cb-4e9f-876a-ea3bfa6e47bd"
}

```

```java
UrbanAirshipClient client = UrbanAirshipClient.newBuilder()
        .setKey("<app key>")
        .setSecret("<master secret>")
        .build();
        
UpdateEmailChannel updateEmailChannel = UpdateEmailChannel.newBuilder()
        .setAddress("name@example.com")
        .setEmailOptInLevel(OptInLevel.EMAIL_COMMERCIAL_OPTED_IN, "2021-10-28T10:34:22")
        .setEmailOptInLevel(OptInLevel.EMAIL_TRANSACTIONAL_OPTED_IN,"2021-10-28T10:34:22")
        .build();

UpdateEmailChannelRequest updateEmailChannelRequest = UpdateEmailChannelRequest.newRequest("6c8f1d3a-64d8-4ef9-b7a1-9b128013327e", updateEmailChannel);
Response<EmailChannelResponse> response = client.execute(updateEmailChannelRequest);

```

```python
from urbanairship import (
    BearerTokenClient, Email
)

client = BearerTokenClient(
    app_key='<app_key>',
    token='<bearer_token>'
)

email = Email(
    client=client,
    address='tommy@example.com',
    commercial_opted_in='2020-10-28T10:34:22'
)

response = email.update(channel_id='251d3318-b3cb-4e9f-876a-ea3bfa6e47bd')

```

```ruby
require 'urbanairship'

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

email_channel = UA::Email.new(client: airship)
email_channel.channel_id = '251d3318-b3cb-4e9f-876a-ea3bfa6e47bd'
email_channel.type = 'email'
email_channel.commercial_opted_in = '2020-10-28T10:34:22'
email_channel.update

```

---

