# Attributes {{< glossary_definition "attribute" >}} # About attributes > {{< glossary_definition "attribute" >}} ## Tags versus attributes Consider the example below — you want to target fans of the actor Chris Pine. To accomplish this, you specify an audience of users with the [tag](https://www.airship.com/docs/reference/glossary/#tag) `chris_pine`. Either a user has this tag, or not. **Note:** These API examples can also be used in the dashboard. **Tag audience** ```json { "audience": { "tag": "chris_pine" } } ``` But let's say you wanted to target fans of **All The Chrises**: Chris Pine, Chris Evans, Chris Pratt, and Chris Hemsworth. With attributes, you can set your audience to target users whose `favorite_actor` attribute `contains` the value `chris`, and you will reach all the Chris fans. **Attributes audience** ```json { "audience": { "attribute": "favorite_actor", "operator": "contains", "value": "chris" } } ``` It's a silly example, but hopefully you can begin to see the power of comparison operators for attributes. ## Attribute types User information can be stored in an attribute as text or as a number, date, or JSON object. Each attribute type is named for the schema that defines what values it accepts. Text, Number, and Date schemas are determined by Airship. You provide your own schema for JSON attributes. Values accepted for each attribute type: | Attribute type | Value format | Comments | | --- | --- | --- | | **Text** | String | Text strings can be a maximum of 255 characters. | | **Number** | Number or float value | When setting Number attributes, you can provide your value as an integer, float, or string. | | **Date** | ISO 8601 date-time formatted string: `YYYY-MM-DDTHH:MM:SS` | You can set an offset by appending the date-time with `+HH:MM`. For example, `2020-07-20T12:35:42+08:00`. Date attributes are converted to and stored as UTC. | | **JSON** | An object containing one or more string, number, date, or boolean key-value pairs, individually or within objects or arrays | JSON attributes are not available in [Performance Analytics](https://www.airship.com/docs/reference/glossary/#pa). See following page section for additional information. | ### JSON attributes JSON attributes are data objects containing one or more string, number, date, or boolean key-value pairs. The pairs can be added individually or within objects or arrays. You can think of them as collections of information you can assign to a user. Example use cases: * **Retailer** — Store user preferences and send sale or discount messages about items you know a user will be interested in and with personalized content for their preferred brands, colors, etc. * **Airline** — Store a user's booking information and send confirmation and update messages leading up to, during, and after their trip. Messages would contain their confirmation code, flight numbers, origin and destination airport codes, and departure and arrival times. For each JSON attribute, you create a template for the structure and what data to store. The template is the *schema* and the data is defined as *properties*. Using the above airline use case, you could have an attribute with ID `reservation` and create a schema for the confirmation code and lists of like data types (departures and arrivals) with properties for flight numbers, airport codes, and times. In addition to the properties defined in your provided schema, each JSON attribute has a property `exp` for its expiration date, represented as the number of seconds since the epoch (January 1st, 1970). After expiration, Airship ignores the attribute where used in segmentation and personalization. When setting a JSON attribute on a user, if a value for `exp` is not provided, Airship automatically sets a value of 90 days from the current date and time. The maximum expiry delay for a JSON attribute is 731 days. Each instance of setting a JSON attribute on a user is defined by an *instance ID*, which is used as a reference for the property values set for that user. The following describes associating the data with users and targeting and personalization options: | Topic | How it works | Airline use case example | | --- | --- | --- | | **Setting the attribute on your audience** | Use the SDKs or API to set JSON attributes on a user, specifying an instance ID and values for properties. | When a user books a round-trip flight, you could assign the `reservation` attribute with instance ID `a001`. The JSON data assigned for instance `reservation#a001` would contain a list of each flight leg going to the destination and each returning flight leg. | | **Targeting the attribute** | You target a JSON attribute's properties, not the object as a whole. All instances of the attribute are evaluated for matches. Any user that matches the target is included in the message audience. | For a flight update message, you could target any user with the attribute `reservation` where the initial leg of their trip departs from airport `PDX`. Any user with that attribute and value `PDX` for the airport code property would be included in the message audience. | | **Personalizing content** | In message content, you can reference JSON attributes by instance ID or evaluate all instances of the attribute. In both cases, the message content populates with the property values set for a user. | In a flight update message, you could reference `reservation` properties, and the message would contain user-specific details about how the change affects their trip. | ## Categories, data sources, and setup Attributes can come from the Airship SDKs, users, and you. Data sources, descriptions, and setup per attribute category: | Category | Data source | Description | Setup | | --- | --- | --- | --- | | **Default** | Airship SDKs | Airship automatically sets Default attributes on your audience. See [Device properties](https://www.airship.com/docs/guides/audience/device-properties/). | None. | | **Named user ID** | Airship | If a channel has a [named user](https://www.airship.com/docs/reference/glossary/#named_user), Airship automatically generates this attribute, with the named user ID as its value. See [Named user ID attribute](https://www.airship.com/docs/reference/data-collection/attributes/#named-user-id-attribute) in the _Attributes Reference_. | None. | | **NPS survey** | User answers to Net Promoter Score (NPS) surveys in [Scenes](https://www.airship.com/docs/reference/glossary/#scene) | Airship automatically generates attributes based on the NPS score or category. See [NPS Segmentation](https://www.airship.com/docs/guides/features/messaging/scenes/surveys-stories/#nps-segmentation) in _Surveys and Stories_ and [NPS survey attributes](https://www.airship.com/docs/reference/data-collection/attributes/#nps-survey-attributes) in the _Attributes Reference_. | None. | | **Predefined** | Customer | Preformatted Text and Number attributes you can use to ensure consistency across reports and [Performance Analytics](https://www.airship.com/docs/reference/glossary/#pa). For example, ID `first_name` for first name, and ID `last_name` for last name. See [Predefined attributes](https://www.airship.com/docs/reference/data-collection/attributes/#predefined-attributes) in the _Attributes Reference_. | Add attributes in your project settings then set them on your audience. | | **Custom** | Customer | You can add any attribute type to your project. | Add attributes in your project settings then set them on your audience. | | **Zero-copy data integration** | Data partner | Directly access user data from external systems. The data remains in its original location instead of being copied or imported into Airship. | See [Zero-copy data integration](https://www.airship.com/docs/guides/features/data-integration/zero-copy-data-integration/). | > **Warning:** To target users based on a unique user ID or other external identifier, do not use Custom attributes. Instead, target [named user](https://www.airship.com/docs/reference/glossary/#named_user). > **Tip:** You can store responses to single choice questions in [Scenes](https://www.airship.com/docs/reference/glossary/#scene) as attributes. > > See the [Question content element](https://www.airship.com/docs/guides/messaging/editors/scenes/elements/#question) in *Configuring Scene content*. ## Personalization You can use attributes in a message body to personalize content for each user. See [Personalizing messages using attributes](https://www.airship.com/docs/guides/personalization/sources/attributes/). # Adding attributes to your project > Before you can target attributes, you must add some types to your project. You must add Predefined and Custom attributes to your project before you can set them on your audience for targeting. You can add up to 250 attributes per project.
After adding attributes, allow at least 10 minutes before setting their values. This delay ensures proper processing of the attributes within Airship.
No setup is required for Default and NPS survey attributes. You can go straight to [Targeting your audience using attributes](https://www.airship.com/docs/guides/audience/attributes/targeting/). Similarly, attributes from [Zero-copy data integration](https://www.airship.com/docs/guides/features/data-integration/zero-copy-data-integration/) are available for targeting once Airship completes your project configuration. ## Add Text, Number, and Date attributes Follow these steps to add text, number, or date attributes to your project: 1. Go to **Audience**, then **Attributes**, then **Attribute List**. 1. Select **Create attribute**. 1. Search for the attribute you want to add. If it matches a [Predefined attribute](https://www.airship.com/docs/reference/data-collection/attributes/#predefined-attributes), select from the results. Results do not include Predefined attributes that have been [archived](https://www.airship.com/docs/guides/audience/attributes/managing/) or already added. 1. Complete the fields: | Field | Description | Steps | | --- | --- | --- | | **Attribute ID** | The key that Airship uses to reference the attribute in the SDKs and API. Letters, numbers, and underscores only, 64 characters maximum. The `ua_` prefix is reserved by Airship, so you cannot include it in the ID. Cannot be edited for Predefined attributes. | Enter text. | | **Name** | A human-friendly name to help you organize and identify your attributes in the dashboard. Accepts all characters, 64 characters maximum. | Enter text. | | **Type** | Determines the format of the attribute value: Text, Number, or Date. Cannot be edited for Predefined attributes. | Select a type. | > **Important:** * Names and IDs must be unique. > * Attribute IDs are case sensitive. If your attributes exist in an external system, make sure they are always the same case in both systems. > * We recommend using lowercase characters with underscores for attribute IDs. For example, `my_text_attribute`. > * You cannot edit a Custom attribute's ID or type after saving. 1. Select **Add**. ## Add JSON attributes When adding a JSON attribute, you must define the object's data structure in a schema. An object is a collection of properties defined as key-value pairs. The values can be strings, numbers, dates, booleans, objects, or arrays. An array is an ordered collection of values. A JSON object allows for nested objects and arrays, so it can contain an array of properties, and those properties can themselves be objects containing more properties and arrays of properties. You can manually enter a schema or automatically generate a schema by uploading a sample .json file. For upload: * The value data determines the value types and will be removed. * Array value type is determined based on the first element in an array, so when using an array with more than one type, the array is converted to a single type based on the first element. For example, the array `["hi", true, 3]` will create an array of strings. * Empty arrays, objects without keys, and keys with empty arrays or objects will be ignored. You can assign any property a more readable name, like "Flight number" or "Reservation code", as an alias. When creating a [segment](https://www.airship.com/docs/reference/glossary/#segment) targeting a JSON attribute, you can select the alias from a menu instead of having to locate the property within the JSON schema. Aliases are supported in the dashboard only. 1. Go to **Audience**, then **Attributes**, then **Attribute List**. 1. Select **Create attribute**. 1. Complete the fields: | Field | Description | Steps | | --- | --- | --- | | **Attribute ID** | A portion of the key that Airship uses to reference the attribute in the SDKs and API. Letters, numbers, and underscores only, 64 characters maximum. The `ua_` prefix is reserved by Airship, so you cannot include it in the ID. | Enter text. | | **Name** | A portion of the key that Airship uses to reference the attribute in the SDKs and API. The name is also used to help you organize and identify your attributes in the dashboard. Letters, numbers, and underscores only, 64 characters maximum. | Enter text. | | **Type** | Determines the format of the attribute value. | Select JSON. | > **Important:** * Names and IDs must be unique. > * Attribute IDs are case sensitive. If your attributes exist in an external system, make sure they are always the same case in both systems. > * We recommend using lowercase characters with underscores for attribute IDs. For example, `my_text_attribute`. > * You cannot edit a Custom attribute's ID or type after saving. > **Tip:** You can select **Add** now to save the attribute, then edit and set up the schema later. 1. (To automatically generate a schema) Select **Upload**, then upload your sample .json file. 1. (To manually create a schema) Select **Create schema**. 1. Edit the schema: | Option | Steps | | --- | --- | | **Add a property** | Select the add icon (+), enter a name, select a value type, then select the check mark. You must also select a value type for each array. | | **Remove a property or object** | Hover over the item, then select the remove icon (trash). | 1. (Optional) Create aliases: 1. Under **Aliases**, select the add icon (+). 1. Enter a name for the alias. 1. Select a property in the schema. Its path will appear next to the alias. 1. (Optional for arrays in the path) Select **First** or **Last** to specify the first or last item in the array. Defaults to **Any**. 1. Select the check mark to save. 1. Repeat for additional aliases. 1. Select **Save JSON Schema**. 1. Select **Add**. # Setting and removing attributes > Setting and removing attributes varies per attribute type. Setting attributes on named users is recommended. For Predefined and Custom attributes, you must set them on your audience after adding them to your project. > **Important:** You must add Custom and Predefined attributes to your project before setting them on users. Otherwise, setting those attributes will result in an error. See [Adding attributes to your project](https://www.airship.com/docs/guides/audience/attributes/adding/). > > JSON attributes cannot be set through CSV upload. Use the Airship SDKs or the [Channels](https://www.airship.com/docs/developer/rest-api/ua/operations/channels/#modifychannelattributes) or [Named Users](https://www.airship.com/docs/developer/rest-api/ua/operations/named-users/#modifynameduserattributes) API. No setup is required for Default and NPS survey attributes. You can go straight to [Targeting your audience using attributes](https://www.airship.com/docs/guides/audience/attributes/targeting/). Similarly, attributes from [Zero-copy data integration](https://www.airship.com/docs/guides/features/data-integration/zero-copy-data-integration/) are available for targeting once Airship completes your project configuration. ## Channels versus named usersYou can set attributes on channels and named users, however their inheritance of attributes varies:
Channels inherit from named users — All the channels associated with a named user will also bear the named users’s attributes. When you remove a channel from a named user, Airship removes attributes set on the named user from that channel.
Using the example favorite_actor attribute contains the value chris, if you store the favorite_actor attribute at the named user level, you can target all contacts who are fans of Chrises over any of their channels. You can keep your audience up to date on Chris-related news, no matter which channels they use to communicate with you.
Named users do not inherit from channels — Any attribute set for a channel will not also be set for an associated named user.
If you store the favorite_actor attribute at the channel level, you can only target fans of Chrises on the specific channels bearing the favorite_actor attribute, limiting the scope of Chris-related communications.
In general, we recommend that you store attributes at the named user level so you can take advantage of your attributes across any of your users’ channels. This helps you build and maintain a cohesive relationship with your audience. Setting attributes at the channel level limits the scope of the attribute to that channel and can also limit your flexibility when targeting audiences.
Named users also inherit a few Default attributes from the last channel that was associated with them, helping keep your named users up to date with scheduling and locale information.
These attributes appear in the user_attributes object:
| Default attribute | Description | Example |
|---|---|---|
| ua_local_tz | The user’s time zone | America/Los_Angeles |
| ua_country | The user’s ISO 3166 two-character country code | US |
| ua_language | The user’s ISO 639-1 two-character language code | en |
After adding attributes, allow at least 10 minutes before setting their values. This delay ensures proper processing of the attributes within Airship.
## Attributes list retention and deletion An attributes list has the same retention behavior whether uploaded in the Airship dashboard, using SFTP, or using the [Attribute Lists API](https://www.airship.com/docs/developer/rest-api/ua/operations/attribute-lists/).Airship automatically deletes a list and all its versions after 90 days of inactivity. Timestamps used to calculate the 90-day period:
The creation date is the initial day one of the 90-day period. Each instance of uploading a new version resets the timestamp to day one.
After deletion, the list is removed from the upload history and is no longer visible in the Airship dashboard or through API calls. Deletion does not affect the project state. For example, if you use an attribute list that adds Attribute A to a channel, Attribute A will still exist on the channel after list deletion. ## Setting and removing Text, Number, and Date attributes You can set and remove Text, Number, and Date attributes using dashboard upload, SFTP, the SDKs, or APIs. Use these formats when setting each attribute type: | Type | Format | | --- | --- | | **Text** | String. When setting Text attributes using a CSV, you do not need to wrap the value in quotes. | | **Number** | Number, float value, or string | | **Date** | ISO 8601 date-time formatted string: `YYYY-MM-DDTHH:MM:SS`. Set an offset by appending the date-time with `+HH:MM`. For example, `2020-07-20T12:35:42+08:00`. | ### CSV file in the dashboard or using SFTP {#csv-file} Whether you want to upload directly from the dashboard or transfer using SFTP, you must first create a list of users and their attributes in a CSV file. Prepare your file using the guidelines in [Attributes CSV Format](https://www.airship.com/docs/reference/messages/csv-formatting/#attributes) in the *CSV Formatting Reference*. When using email or SMS identifiers in your CSV file, Airship registers new channels for addresses or MSISDN/sender combinations that are new to your project. Additional fields indicate opt-in statuses, so that you can send messages to new channels generated from your CSV upload. All values in CSV uploads, including numbers, are represented as strings and cannot be used with [math helpers](https://www.airship.com/docs/guides/personalization/handlebars/math-helpers/). Next, transfer the file using SFTP or upload it in the dashboard. Follow the steps in [SFTP upload for CSV files](https://www.airship.com/docs/guides/audience/segmentation/sftp-upload/), or follow these steps for dashboard upload: 1. Go to **Audience**, then **Attributes**, then **Upload Attribute Data**. 1. For **Upload Type**, select which file type you prepared, **Attributes CSV** or **Attributes Snapshot CSV**. 1. Select **Choose file** and select your file. 1. Select **Upload**. To see your upload and SFTP transfer status, select **Upload History**. See [Viewing upload history](https://www.airship.com/docs/guides/audience/attributes/managing/#viewing-upload-history) in *Managing attributes*. ### SDK To set or remove attributes on a channel or a contact, use the channel or contact classes in our SDKs: * **iOS** — [Contact](https://urbanairship.github.io/ios-library/v20/AirshipCore/documentation/airshipcore/airshipcontact) , [Channel](https://urbanairship.github.io/ios-library/v20/AirshipCore/documentation/airshipcore/airshipchannel) * **Android** — [Channel](https://www.airship.com/docs/reference/libraries/android-kotlin/latest/urbanairship-core/com.urbanairship.channel/-airship-channel/index.html), [Contact](https://www.airship.com/docs/reference/libraries/android-kotlin/latest/urbanairship-core/com.urbanairship.contacts/-contact/index.html) * **Web** — [Channel](https://www.airship.com/docs/reference/libraries/web-notify-sdk/v2-latest/UaSDK.Channel.html#editAttributes), [Contact](https://www.airship.com/docs/reference/libraries/web-notify-sdk/v2-latest/UaSDK.Contact.html#editAttributes) The code examples below show how to set attributes using the provided methods. See the [SDK docs](https://www.airship.com/docs/sdk-topics/attributes/) for more details. #### Android Java ```java Airship.getChannel().editAttributes() .setAttribute("average_rating", 4.99) .setAttribute("last_product_purchased", "A1234567") .removeAttribute("purchase_pending") .apply(); ``` #### iOS Swift ```swift Airship.channel.editAttributes { editor in editor.set(string: "cauldron", attribute: "last_product_purchased") editor.set(number: 4.99, attribute: "average_rating") editor.remove("purchase_pending") } ``` #### iOS Objective-C ```obj-c [UAirship.channel editAttributes:^(UAAttributesEditor * editor) { [editor setString:@"cauldron" attribute:@"last_product_purchased"]; [editor setNumber:@(4.99) attribute:@"average_rating"]; [editor removeAttribute:@"purchase_pending"]; }]; ``` **Setting attributes for Web** ```js const editor = channel.editAttributes() await editor .set("my_attribute", "some_value") .remove("other_attribute") .apply() ``` ### API You can set attribute values from external sources, such as a CRM or data warehouse: * To set attributes on a single channel or named user, use [Set or remove attributes on channels](https://www.airship.com/docs/developer/rest-api/ua/operations/channels/#modifychannelattributes) or [Set or remove attributes on named users](https://www.airship.com/docs/developer/rest-api/ua/operations/named-users/#modifynameduserattributes). Use `set` or `remove` for the `action` value, and use the attribute ID as the `key` value. * To set attributes on many channels or named users at once, use the [Attribute Lists API](https://www.airship.com/docs/developer/rest-api/ua/operations/attribute-lists/) to upload a CSV. **Setting two attributes on a channel and removing another** ```http POST /api/channels/attributes HTTP/1.1 Authorization: BasicFor status “Processed with errors”, select the download icon ( ) to download a CSV file of the identifiers that failed processing and their error reasons.