Skip to main content
Version: 3.x

User attributes and targeting

User attributes allow you to store additional information about users as key-value pairs. Use them to track information such as:

  • Game level
  • Payer status
  • Custom user segments
  • Any other data useful to your organization

SDK setup​

This page covers how to set up user attributes in the Publisher Dashboard.

Important: Attributes only appear in the Publisher Dashboard filters after they've been sent from the SDK at least once.

For platform-specific implementation details, see:

Attribute names must be strings and must not begin with tapresearch_, which is reserved for TapResearch. Use string or numeric values for targeting. For booleans, send "true"/"false" or 0/1 instead of native booleans.

Set clearPreviousAttributes to false to merge new values with existing attributes, or true to replace the attributes you previously sent.

Targeting based on user attributes​

You can add up to 3 filters per piece of content.

Note: Capping and pacing is only available for currency sale banner content, not Multiple Choice questions.

Example: Targeting users in France​

Currency sale banner editor with a Target audience filter of Country is equal to FR

The screenshot shows a partial list of targeting criteria received by TapResearch. Sending different attributes enables you to target different user segments.

Target audience filter dropdown listing user attributes received from the SDK

Targeting operators​

  • is equal to - Match a specific value, or any value in a list of values
  • does not equal - Exclude a specific value
  • is greater/equal to and is less/equal to - Numerical comparisons. For date attributes such as First Seen At, these appear as is newer than and is older than
Target audience operator dropdown: is equal to, is greater/equal to, is less/equal to, does not equal

Multiple values for one attribute: Add each value as its own separate entry in the filter — for example, three separate entries for US, CA, and GB when targeting multiple countries, or three separate entries for each tenure level. Do not enter them as a single comma-separated string (e.g. US, CA, GB) — the filter will treat that as one literal value and it won't match anything.

Important limitations​

  • Case sensitivity - Attributes are case-sensitive: test and Test are different attributes
  • Dates - Stored as strings: 2020-01-01 and 2020-1-1 are different values
  • Booleans - Do not use native booleans. Use stringified values ("true") or integers (0, 1) instead
  • Integer vs String - 1 and "1" are different values. For numerical comparisons, send integer values

Built-in attributes​

These built-in attributes are also available for targeting:

Country​

The user's country location.

  • Use 2-letter ISO country codes (e.g., US for United States)

First Seen At​

The first time TapResearch saw this user.

  • Use ISO8601 date strings: 2020-01-01T00:00:00.000Z
  • Use relative dates: 3d targets users seen more than 3 days ago
  • Date-only format works: 2020-01-01 equals 2020-01-01T00:00:00.000Z

Test Devices​

Targets only devices in your Test device list.

  • Use for testing content before going live

Audience Percentage​

Targets a percentage of users.

  • Select groups out of 10 (each group = 10% of users)
  • Example: Select 3 groups to target 30% of users

Examples​

userAttributes = hashMapOf(
"testStatus" to "VIP",
"testInt" to 2,
"testIntString" to "2",
"vip_status" to "super-vip",
"Some Date" to Instant.now().toString(), // 2023-08-31T10:15:30.00Z
// The below will match on relative dates, so you can filter by "a Month Ago" >= 3d
"a Month Ago" to LocalDate.now().minus(1, ChronoUnit.MONTHS).toString(), // 2023-07-31
"testCAPSUpper" to "CAPS", // Matches "CAPS" but not "caps"
"testCAPSLower" to "caps", // Matches "caps" but not "CAPS"
),

Technical details​

Attribute caching​

User attributes are cached for 1 minute on the backend.

  • Changes to attributes may take up to 1 minute to be reflected when querying for content

Caching examples​

Example 1: User Levels Up

Scenario: User sees a placement, levels up, and views the same placement again.

playerLevel = 1 changes to playerLevel = 2

You have two pieces of content, one for level 1 and one for level 2.

  • The user shows content for a placement
  • The user's level is 1
  • The user plays the game and levels up to 2
  • The user clicks the placement again and its been less than 1m
  • The user sees the same content for that placement, not the level 2 content

Example 2: New Attribute Added

Scenario: You have two pieces of content, one for attribute 1 and one for attribute 2.

attribute1 = 1

You add an attribute

attribute2 = 2

The user has seen a placement, gets an additional attribute they did not have before, and sees new content for that placement

  • The user shows content for a placement
  • The user has an additional attribute added to their user attributes that did not exist before
  • The user clicks the placement again and its been less than 1m
  • The user sees the new content for that placement, based on the filters for that content

Example 3: Date Targeting

  • Relative dates
    • You want to show content to users who have been playing for 1 month
    • You'll want to target where First seen at <= 30d
  • Absolute dates
    • You want to show content to users who have been playing for 1 month
    • You'll want to target where First seen at <= 2020-01-01T00:00:00.000Z

Example 4: Boolean Values

  • A user is a VIP
    • String
      • Send the attribute is_vip = "true"
      • You'll want to target where is_vip = "true"
    • Integer
      • Send the attribute is_vip = 1
      • You'll want to target where is_vip = 1

Example 5: Multiple Values

  • You have multiple user types and want to target some of them
    • Send the attribute user_type = "vip" or user_type = "normal" or user_type = "super-vip"
    • Target where user_type = "vip" or user_type = "super-vip" using the is equal to operator — add vip and super-vip as two separate entries in the filter UI, not as one comma-separated value

Troubleshooting​

Content not matching?​

Common issue: Sending strings instead of integers

  • Sending "1" (string) will not match filters expecting 1 (integer)
  • Solution: Send the value as an integer: 1