> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/concepts/user-attributes.md).

# User attributes

What Amply knows about a user. Attributes come from three places: the device itself, the app install, and what your code tells Amply. Targeting rules, frequency caps, and campaign conditions are all built on top of these.

## Three sources of attributes

| Source            | Who sets it            | Examples                                                  |
| ----------------- | ---------------------- | --------------------------------------------------------- |
| Device attributes | The SDK, automatically | Platform, OS version, country, device model               |
| App attributes    | The SDK, automatically | Install date, app version at install, current app version |
| User attributes   | You, from app code     | User ID, plan tier, premium status, account age           |

You rarely think about the boundary when you are writing rules in the dashboard — the rule builder shows all three groups together. But it helps to know which is which when you are asking "can I target on this?"

## Device attributes — automatic

The SDK collects these from the platform. You do not need to write any code.

* **Platform** — iOS or Android.
* **OS version** — the operating system version.
* **Country** — derived from the device locale.
* **Application** — which of your apps this is (relevant for projects with more than one app).

Device attributes describe the environment. They are good for rolling out a campaign only on one platform, or gating on a minimum OS version.

## App attributes — automatic

These describe the install and the usage.

* **Install date** — when the app was first installed on this device.
* **App install version** — the app version at install time. Useful for distinguishing long-time users from recent installs.
* **App version** — the app version currently running.

App attributes describe the user's relationship to your app over time. They let you ask "is this a brand-new user or a returning one?", "which cohort did they install into?"

> **Note — session count.** The SDK tracks session count internally, but it is not currently exposed as a built-in targeting attribute in the rule builder. To target on session count, set it as a custom property from your app on every session start — see [Sessions and events](/concepts/sessions-and-events.md).

## User attributes — you set these

This is the only group your code controls. There are two calls you need to know:

* **`setUserId(userId)`** — attach a stable identifier to this device. Call it when the user logs in. Call it with `null` to clear on logout.
* **`setCustomProperty(key, value)`** — store a named value for this user. Call it whenever the value changes.

Custom properties take primitive values. The SDK supports strings, numbers, and booleans on every platform. The iOS and Android native SDKs additionally support date/time values. Nested objects and arrays are not supported — keep values flat.

Examples of custom properties worth setting:

* `plan` — "free", "pro", "team"
* `premium` — true / false
* `trial_ends_at` — a date
* `signup_source` — "organic", "paid\_ads", "referral"
* `account_tier` — 1, 2, 3

Custom properties are the bridge between your app's internal state and Amply's targeting. If you want to target "users on the pro plan", someone has to call `setCustomProperty("plan", "pro")` when the user's plan becomes pro.

## When to use which

* You want to roll out to a platform or OS → **device attribute**.
* You want to gate on "how long have they used the app" → **app attribute** (install date) or a custom property (session count, time-in-app).
* You want to gate on a product concept your app owns (subscription state, account type, premium tier, experiment cohort) → **user attribute** (custom property).

Rule of thumb: if the value lives inside your app's business logic, it is a custom property. If it comes from the device or the install, the SDK has it for free.

## Identifying the same user across installs

`setUserId` is how you keep targeting stable when the user reinstalls, moves devices, or logs in on a second device. The device is what Amply sees by default; `setUserId` gives you a stable handle on top of that.

Set the user ID as soon as you have one. Clear it (pass `null`) on logout so the next user on the same device does not inherit the previous user's properties.

## Custom property lifecycle

Custom properties persist on the device. Once you set a property, it stays until:

* You call `setCustomProperty` again with the same key (overwrite).
* You call `removeCustomProperty(key)` (delete one).
* You call `clearCustomProperties()` (delete all).
* The user uninstalls the app.

The persistence means you do not need to re-set properties on every app launch. Set them when they change.

## React to a property changing

Targeting on a custom property answers "who is this user *right now*." But sometimes the moment of change is the opportunity. Every time a custom property is set, updated, removed, or cleared, Amply emits a `CustomPropertyChanged` event — and you can use that event as a campaign **trigger**.

That means you can react to the instant a trait flips, not just to its current value. For example, fire a winback the moment `plan_tier` becomes `free` — the change itself is the signal, so the campaign runs at exactly the right beat instead of waiting for the next session or event. The event carries the property key plus its old and new value, so a trigger can condition on the direction of the change. See [Events](/reference/events.md) for the exact parameters.

See [Tracking events](/developer-guide/tracking-events.md) for event tracking, and [User attributes (dev)](/developer-guide/user-attributes.md) for the exact signatures.

## What is already there vs. what you have to set

| Attribute           | Automatic?                 | Notes                                                |
| ------------------- | -------------------------- | ---------------------------------------------------- |
| Platform            | yes                        | iOS / Android                                        |
| OS version          | yes                        |                                                      |
| Country             | yes                        | derived from locale                                  |
| App version         | yes                        | current version                                      |
| App install version | yes                        | the version at install time                          |
| Install date        | yes                        | first install                                        |
| Session counter     | tracked but not targetable | set as a custom property if you need to target on it |
| User ID             | no                         | call `setUserId` on login                            |
| Custom properties   | no                         | call `setCustomProperty` whenever values change      |

## Related

* [Targeting and audiences](/concepts/targeting-and-audiences.md) — how attributes become rules
* [Sessions and events](/concepts/sessions-and-events.md) — the other half of what Amply knows
* [User attributes (dev)](/developer-guide/user-attributes.md) — SDK calls in code
* [Tracking events](/developer-guide/tracking-events.md) — complementary: events describe behavior, attributes describe identity


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amply.tools/concepts/user-attributes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
