> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# v3-4 SDK Data Tag SDK Methods

> Available options to add Tags to devices with OneSignal.

<Warning>
  The methods below require the OneSignal SDK versions 3 & 4.

  It is recommended to upgrade to our latest version 5 SDKs for User Model APIs.

  See [Update to User Model](/docs/en/user-model-migration-guide) for migration steps.
</Warning>

OneSignal tags are custom `key : value` pairs of string data for setting custom user or event properties. This guide details how to add tags through the SDK, but tags can be set in a number of ways outlined in [Tags: Tracking User Events and Attributes](/docs/en/add-user-data-tags)

Tags should be added as `string` data, but any numbers/integers/decimals will be detected automatically on our backend and available for use.

<Warning>
  Do not use tags for setting "user Ids" or sending messages to individual users. Instead use the [External User Id](/docs/en/users) property.

  OneSignal is not meant to be a database. If you wish to store complex user attributes, we recommend using a dedicated [Database, DMP, or CRM](/docs/en/database-dmp-crm-integration).
</Warning>

# SDK Tagging Methods

Tag a user based on an event of your choosing so later you can create [Segments](/docs/en/segmentation) or [Message Personalization](/docs/en/message-personalization). Recommend using `sendTags` over `sendTag` if you need to set more than one tag on a user at a time.

iOS SDK implements callbacks to verify tags were successfully added. Android saves tags to device cache and will retry updating the tag automatically upon a stable network connection being established.

## `sendTag` Method

Tag a user based on an app event of your choosing so later you can later create segments to target these users. We recommend using `sendTags` over `sendTag` if you need to add or update more than one tag on a user at a time.

If you try to set more tags on a user than you plan allows, it will fail. You will need to delete any unwanted tags first before setting or updating tags. See [Data Tags](/docs/en/add-user-data-tags) for details.

| Parameter             | Type                        | Description                                                                                                                                                                                 |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key`                 | String, NSString\*          | Key of your choosing to create or update                                                                                                                                                    |
| `value`               | String, NSString\*          | Value to set on the key. *NOTE:* Passing in a blank String deletes the key, you can also call `deleteTag` or `deleteTags`.                                                                  |
| `onSuccess(Optional)` | OneSignalResultSuccessBlock | **iOS** Called if there were no errors sending the tag.                                                                                                                                     |
| `onFailure(Optional)` | OneSignalFailureBlock       | **iOS** Called if there was an error. **Android** Will retry automatically upon a stable network connection.                                                                                |
| `callback` (Web)      | Function                    | Call back to be fired when the tags have been sent to our server and a response has been returned. The first parameter of the callback is an object of the tags you sent (key-value pairs). |

<CodeGroup>
  ```javascript Web (js) theme={null}
  //Returns a Promise resolving with the object key-pairs of the tags you sent, 
  //or rejected with an error.

  //Example with callback
  OneSignal.push(function() {
    OneSignal.sendTag("key", "value", function(tagsSent) {
      // Callback called when tags have finished sending
    });
  });

  // Another callback example
  OneSignal.push(function() {            
    OneSignal.sendTag("key", "value").then(function(tagsSent) {
      // Callback called when tags have finished sending
    }); 
  });

  //Example without callback
  OneSignal.push(function() {
    /* These examples are all valid */
    OneSignal.sendTag("key", "value"); 
  });
  ```

  ```java java theme={null}
  OneSignal.sendTag("key", "value");
  ```

  ```swift Swift theme={null}
  OneSignal.sendTag("key", value: "value")
  ```

  ```objectivec objectivec theme={null}
  [OneSignal sendTag:@"key" value:@"value"];
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.SendTag("tagName", "tagValue");
  ```

  ```javascript React Native theme={null}
  OneSignal.sendTag("key", "value");
  ```

  ```javascript Cordova/Ionic theme={null}
  window.plugins.OneSignal.sendTag("key", "value");
  ```

  ```javascript Flutter theme={null}
  //Example without callback
  OneSignal.shared.sendTag("test", "value");

  //Example with callback
  OneSignal.shared.sendTag("key", "value").then((response) {
    print("Successfully sent tags with response: $response");
  }).catchError((error) {
    print("Encountered an error sending tags: $error");
  });
  ```

  ```csharp Xamarin theme={null}
  OneSignal.Current.SendTag("key", "value");
  ```

  ```lua Corona theme={null}
  OneSignal.SendTag("CoronaTag1", "value1")
  ```
</CodeGroup>

## `sendTags` Method

Tag a user based on an app event of your choosing, so that later you can create segments to target these users. If you try to set more tags on a user than you plan allows, it will fail. You will need to delete any unwanted tags first before setting or updating tags. See [Data Tags](/docs/en/add-user-data-tags) for details.

| Parameter             | Type                        | Description                                                                                                                                                                                 |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `keyValues`           | JSONObject, NSDictionary\*  | Key value pairs of your choosing to create or update. *NOTE:* Passing in a blank `NSString*` as a value deletes the key, you can also call `deleteTag` or `deleteTags`.                     |
| `onSuccess(Optional)` | OneSignalResultSuccessBlock | **iOS** Called if there were no errors sending the tag.                                                                                                                                     |
| `onFailure(Optional)` | OneSignalFailureBlock       | **iOS** Called if there was an error. **Android** Will retry automatically upon a stable network connection.                                                                                |
| `callback` (Web)      | Function                    | Call back to be fired when the tags have been sent to our server and a response has been returned. The first parameter of the callback is an object of the tags you sent (key-value pairs). |

<CodeGroup>
  ```javascript Web (js) theme={null}
  //Returns a Promise resolving with the object key-pairs of the tags you sent, 
  //or rejected with an error.

  //Example with callback
  OneSignal.push(function() {
    OneSignal.sendTags({
      key: 'value',
      key2: 'value2',
    }, function(tagsSent) {
      // Callback called when tags have finished sending    
    });
  });

  //Another example with callback
  OneSignal.push(function() {
    OneSignal.sendTags({
      key: 'value',
      key2: 'value2',
    }).then(function(tagsSent) {
      // Callback called when tags have finished sending    
    });
  });

  //Example without callback
  OneSignal.push(function() {
    OneSignal.sendTags({key: 'value'});
  });

  //Another example without callback
  OneSignal.push(function() {
    OneSignal.sendTags({
      key: 'value',
      key2: 'value2',
    });
  });
  ```

  ```java java theme={null}
  JSONObject tags = new JSONObject();
  tags.put("key1", "value1");
  tags.put("key2", "value2");
  OneSignal.sendTags(tags);
  ```

  ```swift Swift theme={null}
  OneSignal.sendTags(["key1": "value1", "key2": "value2"])
  ```

  ```objectivec objectivec theme={null}
  [OneSignal sendTags:@{@"key1" : @"value1", @"key2" : @"value2"}];
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.SendTags(new Dictionary<string, object> { 
      { "tag1", "123" },
      { "tag2", "abc" }
  });
  ```

  ```javascript React Native theme={null}
  OneSignal.sendTags({key: "value", key2: "value2"});
  ```

  ```javascript Cordova/Ionic theme={null}
  window.plugins.OneSignal.sendTags({key: "value", key2: "value2"});
  ```

  ```javascript Flutter theme={null}
  //Example without callback
  OneSignal.shared.sendTags({"test_key_1" : "test_value_1", "test_key_2" : "test_value_2"});

  //Example with callback
  OneSignal.shared.sendTags({"test_key_1" : "test_value_1", "test_key_2" : "test_value_2"})
  .then((response) {
    print("Successfully sent tags with response: $response");
  }).catchError((error) {
    print("Encountered an error sending tags: $error");
  });
  ```

  ```csharp Xamarin theme={null}
  OneSignal.Current.SendTags(new Dictionary<string, string>() { {"TestKey2", "value2"}, {"TestKey3", "value3"} });
  ```

  ```lua Corona theme={null}
  OneSignal.SendTags({["CoronaTag2"] = "value2",["CoronaTag3"] = "value3"})
  ```
</CodeGroup>

## `getTags` Method

Retrieve a list of tags as that have been set on the user from the OneSignal server. Android will provide a cached copy if there is no network connection.

<CodeGroup>
  ```javascript Web (js) theme={null}
  //Returns a Promise resolving with the object key-pairs of the tags you sent
  //or rejected with an error.

  //All examples are valid.

  OneSignal.push(function() {
    OneSignal.getTags(function(tags) {
      // All the tags stored on the current webpage visitor
    });
  });

  OneSignal.push(function() {
    OneSignal.getTags().then(function(tags) {
      // All the tags stored on the current webpage visitor
    });
  });

  OneSignal.push(["getTags", function(tags) {
  	console.log("OneSignal getTags:");
    console.log(tags);
  }]);
  ```

  ```java java theme={null}
  //The tagsAvailable callback does not return on the Main(UI) Thread, so be aware when modifying UI in this method.
  OneSignal.getTags(new OSGetTagsHandler() {
  	@Override
  	public void tagsAvailable(JSONObject tags) {
      //tags can be null
      if (tags !== null) {
        Log.d("debug", tags.toString());
      }
    }
  });
  ```

  ```swift Swift theme={null}
  OneSignal.getTags({ tags in
  	print("tags - \(tags!)")
  }, onFailure: { error in
  	print("Error getting tags - \(error?.localizedDescription)")
  })
  ```

  ```objectivec objectivec theme={null}
  [oneSignal getTags:^(NSDictionary* tags) {
  	NSLog(@"%@", tags);
  }];
  ```

  ```csharp Unity (C#) theme={null}
  var tags = await OneSignal.Default.GetTags();
  var tag3Value = tags["tag3"];
  ```

  ```javascript React Native theme={null}
  OneSignal.getTags((receivedTags) => {
      console.log(receivedTags);
  })
  ```

  ```javascript Cordova/Ionic theme={null}
  window.plugins.OneSignal.getTags(function(tags) {
    console.log('Tags Received: ' + JSON.stringify(tags));
  });
  ```

  ```javascript Flutter theme={null}
  Map<String, dynamic> tags = await OneSignal.shared.getTags();
  ```

  ```csharp Xamarin theme={null}
  void SomeMethod() {
  		OneSignal.GetTags(TagsReceived);
  	}

  	private void TagsReceived(Dictionary<string, object> tags) {
  		foreach (var tag in tags)
  			print(tag.Key + ":" + tag.Value);
  	}
  ```

  ```lua Corona theme={null}
  function printAllTags(tags)
     for key,value in pairs(tags) do
        print( key, value )
     end
  end

  OneSignal.GetTags(printAllTags)
  ```
</CodeGroup>

| Parameter                    | Type                         | Description                                                                                                                                             |
| ---------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tags`                       | JSON Object of `String` data | Contains key-value pairs retrieved from the OneSignal server.                                                                                           |
| `successBlock`               | OneSignalResultSuccessBlock  | Called when tags are received from OneSignal's server.                                                                                                  |
| `onFailure(Optional)`        | OneSignalFailureBlock        | Called if there was an error.                                                                                                                           |
| `tagsReceivedCallBack` (Web) | Function (Web)               | Callback to be fired when the list of tags has been retrieved. The first parameter of the callback is an object containing key-value pairs of the tags. |

## `deleteTag` Method

Deletes a single tag that was previously set on a user with `sendTag` or `sendTags`. Use `deleteTags` if you need to delete more than one.

| Parameter             | Type                        | Description                                                                                                 |
| --------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `key`                 | String, NSString\*          | Key to remove                                                                                               |
| `onSuccess(Optional)` | OneSignalResultSuccessBlock | **iOS** Called if there were no errors                                                                      |
| `onFailure(Optional)` | OneSignalFailureBlock       | **iOS** Called if there was an error **Android** Will retry automatically upon a stable network connection. |

<CodeGroup>
  ```javascript Web (js) theme={null}
  //Returns a Promise resolving with the object key-pair of the tag you deleted, 
  //or rejected with an error.
  OneSignal.push(function() {
    OneSignal.deleteTag("tagKey");
  });
  ```

  ```java java theme={null}
  OneSignal.deleteTag("key");
  ```

  ```swift Swift theme={null}
  OneSignal.deleteTag("key")
  ```

  ```objectivec objectivec theme={null}
  [OneSignal deleteTag:@"key"];
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.DeleteTag("tag4");
  ```

  ```javascript React Native theme={null}
  OneSignal.deleteTag("key");
  ```

  ```javascript Cordova/Ionic theme={null}
  window.plugins.OneSignal.deleteTag("key");
  ```

  ```javascript Flutter theme={null}
  await OneSignal.shared.deleteTag("test");
  ```

  ```csharp Xamarin theme={null}
  OneSignal.DeleteTag("key");
  ```

  ```lua Corona theme={null}
  OneSignal.DeleteTag("CoronaTag1")
  ```
</CodeGroup>

## `deleteTags` Method

Deletes one or more tags that were previously set on a user with `sendTag` or `sendTags`.

| Parameter             | Type                         | Description                                                                                                                                 |
| --------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `keys`                | Array, Collection, NSArray\* | Keys to remove.                                                                                                                             |
| `onSuccess(Optional)` | OneSignalResultSuccessBlock  | **iOS** Called if there were no errors                                                                                                      |
| `onFailure(Optional)` | OneSignalFailureBlock        | **iOS** Called if there was an error **Android** Will retry automatically upon a stable network connection.                                 |
| `callback` (Web)      | Function                     | Callback to be fired when the list of tags has been removed. The first parameter of the callback is an array of the tags that were deleted. |

<CodeGroup>
  ```javascript Web (js) theme={null}
  //Returns a Promise resolving with the object key-pair of the tag you deleted, 
  //or rejected with an error.

  //All examples are valid.

  OneSignal.push(function() {
    OneSignal.deleteTags(["key1", "key2"], function(tagsDeleted) {
      // Callback called when tags have been deleted    
    });
  });

  OneSignal.push(function() {
    OneSignal.deleteTags(["key1", "key2"]).then(function(tagsDeleted) {
    });
  });
  ```

  ```java java theme={null}
  Collection<String> tempList = new ArrayList<String>();
  tempList.add(key);
  OneSignal.deleteTags(tempList);
  ```

  ```swift Swift theme={null}
  OneSignal.deleteTags(["key1", "key2"])
  ```

  ```objectivec objectivec theme={null}
  [OneSignal deleteTags:@[@"key1", @"key2"]];
  ```

  ```csharp Unity (C#) theme={null}
  OneSignal.Default.DeleteTags(new[] { "tag5", "tag6" });
  ```

  ```javascript React Native theme={null}
  OneSignal.deleteTags(["key1", "key2"]);
  ```

  ```javascript Cordova/Ionic theme={null}
  window.plugins.OneSignal.deleteTags(["key1", "key2"]);
  ```

  ```javascript Flutter theme={null}
  await OneSignal.shared.deleteTags(["test_key_1", "test_key_2"]);
  ```

  ```csharp Xamarin theme={null}
  OneSignal.Current.DeleteTags(new List<string>() {"TestKey2", "TestKey3" })
  ```

  ```lua Corona theme={null}
  OneSignal.DeleteTags({"key1", "key2"})
  ```
</CodeGroup>

***

# Tagging Examples

## Tag Based on Browser or Operating System

OneSignal currently tracks `device type`, which you can use to create [Segments](/docs/en/segmentation) to target Android and iOS mobile app subscribers and Web Push subscribers independently.

If you want to segment by mobile web vs. desktop web subscribers, you can use this example code on the site to tag automatically once detected:

<CodeGroup>
  ```javascript javascript theme={null}
  // Example from Stackoverflow https://stackoverflow.com/questions/1005153/auto-detect-mobile-browser-via-user-agent
  OneSignal.push(function() {
    if (navigator.appVersion.indexOf("Mobile") > -1) {
      OneSignal.sendTag("device_type","mobile");
    } else {
      OneSignal.sendTag("device_type","desktop");
    }
  });
  ```
</CodeGroup>

For segmenting around all different types of Operating Systems and Browsers, you can use this more in-depth tagging options:

<CodeGroup>
  ```javascript javascript theme={null}
  // Example from Stackoverflow: https://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
  var os = "Unknown OS";
  if (navigator.userAgent.indexOf("Win") != -1) os = "Windows";
  if (navigator.userAgent.indexOf("Mac") != -1) os = "Macintosh";
  if (navigator.userAgent.indexOf("Linux") != -1) os = "Linux";
  if (navigator.userAgent.indexOf("Android") != -1) os = "Android";
  if (navigator.userAgent.indexOf("like Mac") != -1) os = "iOS";
  console.log('Your os: ' + os);

  var browserType = "Unknown Browser Type";
  if (navigator.userAgent.indexOf("Safari") != -1) browserType = "Safari";
  if (navigator.userAgent.indexOf("Chrome") != -1) browserType = "Chrome";
  if (navigator.userAgent.indexOf("OPR") != -1) browserType = "Opera";
  if (navigator.userAgent.indexOf("Firefox") != -1) browserType = "Firefox";
  console.log('Your Browser: ' + browserType);

  OneSignal.push(function() {
    OneSignal.sendTags({
      os: os,
      browserType: browserType,
    }).then(function(tagsSent) {
      // Callback called when tags have finished sending 
      console.log("tagsSent: ", tagsSent);
    });
  });
  ```
</CodeGroup>

## Get and Delete All Tags

Example of fetching all tags and deleting them.

<CodeGroup>
  ```swift Swift theme={null}
  OneSignal.getTags({tagsReceived in
      print("tagsReceived: ", tagsReceived.debugDescription)
      var tagsArray = [String]()
      if let tagsHashableDictionary = tagsReceived {
        tagsHashableDictionary.forEach({
          if let asString = $0.key as? String {
            tagsArray += [asString]
          }
        })
      }
      print("tagsArray: ", tagsArray)
      OneSignal.deleteTags(tagsArray, onSuccess: { tagsDeleted in
          print("tags deleted success: ", tagsDeleted.debugDescription)
      }, onFailure: { error in
          print("deleting tags error: ", error.debugDescription)
      })
  })
  ```
</CodeGroup>

***
