User Profiles & Custom Data

Attach your own key-value data and tags to visitors

A user profile is the record Transfon Security keeps for each visitor of a Tag Mode project. On its own the profile only contains what the tag can observe — IP addresses, user agents, page views. With the JavaScript API you can attach your own key-value data to it: an email address, a plan name, a customer ID, lifetime value, tags such as beta or vip.

Once attached, that data is shown on the User Profiles tab and in the Custom Data & Tags section of the profile panel, and it can be used to filter events and profiles.

User profiles are available in Tag Mode projects only. Gateway Mode projects log requests without a client-side tag, so there is no browser to send custom data from.

How a visitor is identified

The tag stores a random UUID in a first-party cookie named __unis_uid (valid for 301 days) and sends it with every event. A profile is keyed by project + UUID, so:

  • The same browser keeps the same profile across visits until the cookie is cleared.
  • The same person on a second device or after clearing cookies gets a second profile.
  • Profiles are not shared between projects, but the Recent Activity list in the profile panel does span every Tag Mode project in your organization.

Because the UUID is anonymous until you say otherwise, sending email (or your own customer ID) is what ties a profile to a real account.

Sending custom data

Custom data is sent with the reserved event name sync:

window._waf360.send("sync", {
  email: "[email protected]",
  name: "Jane Doe",
  plan: "pro",
  mrr: 49.9,
  seats: 12,
  approved: true,
  signup_date: "2025-03-14",
  segments: ["beta", "eu"]
});

Key points:

  • Only sync events write to the profile. Any other event name (pv, signup, your own custom events) is recorded as an event, but its payload is not merged into the profile.
  • Call it as soon as you know who the visitor is — after login, after a checkout, or on every page render from your server-side session.
  • It is safe to call before the tag script has loaded, as long as the queue stub is in place. See Installation in the JavaScript API guide.
  • Keys and values are merged into the existing profile, so you can send a partial payload at any time.

Sending only what changed

There is no need to resend the whole profile on every page. A later sync updates the keys it carries and leaves every other key untouched:

// on login
window._waf360.send("sync", { email: "[email protected]", name: "Jane Doe" });

// later, after an upgrade — email and name are kept
window._waf360.send("sync", { plan: "enterprise", mrr: 499 });

For a scalar key (string, number, boolean, date) the last value wins. Array values behave differently — see Tags.

Recognized keys

Two keys are used by the dashboard itself:

KeyUsed for
emailProfile subtitle, the Email filter on the User Profiles tab, and the email column in the events table
nameThe display name at the top of the profile card and panel

Every other key is stored as custom data and shown in the Custom Data & Tags section of the profile panel.

Value types

Each value keeps a type, which is what makes numeric and date comparisons possible. The type is inferred from the value you send:

What you sendStored asExample
true / falseboolean{ approved: true }
Whole numberinteger{ seats: 12 }
Fractional numberfloat{ mrr: 49.9 }
Arraystring array (tags){ segments: ["beta", "eu"] }
Other stringstring{ plan: "pro" }
Objectstring (serialized)avoid — flatten it yourself

Strings that look like something else

Strings are inspected before being stored, so a string that looks like a boolean, a number or a date is converted to that type:

  • "true", "false", "1", "0", "t", "f" become booleans
  • "12" becomes an integer, "49.9" a float
  • "2025-03-14", "2025-03-14 09:30:00" and RFC 3339 / RFC 1123 / RFC 822 timestamps become datetimes

This matters for identifiers. A customer ID sent as { customer_id: "1" } is stored as the boolean true, and { customer_id: "00042" } is stored as the integer 42. If a value is an identifier rather than a quantity, prefix it so it stays a string:

window._waf360.send("sync", { customer_id: "cus_00042" });

Do not send null — it is stored as the literal text <nil>. Omit the key instead, or send an empty string to blank it out.

Tags

Any array value is treated as a set of tags. Later sync calls add to the set instead of replacing it, and duplicates are ignored:

window._waf360.send("sync", { segments: ["beta"] });
window._waf360.send("sync", { segments: ["eu", "beta"] });
// profile now holds: segments = ["beta", "eu"]

To remove a tag, send the value prefixed with a hyphen:

window._waf360.send("sync", { segments: ["-beta"] });
// profile now holds: segments = ["eu"]

Because of this, tags are the right shape for anything a visitor can gain and lose over time — trial cohorts, feature flags, lifecycle stages — while a plain string is the right shape for a value that is simply replaced.

Reserved key names

Alongside your own attributes, a profile holds what Transfon Security observes about the visit: the page and referrer, the user agent, the network and location, and the traffic quality signals. Those observations use key names of their own, and a value you send under one of them is replaced by the observed one.

So keep your keys unmistakably yours and avoid generic request-shaped names such as url, ua, country, ip or tags. A short prefix is the simplest way to stay clear:

window._waf360.send("sync", {
  acct_plan: "pro",
  acct_segments: ["beta", "eu"]
});

email and name are the exception — send those under their own names, since they are the keys the dashboard reads.

Where your data appears

  • User Profiles tab — each card shows name (or email, or the UUID when neither is set), country, IP, event count and last-seen time. Use the Email filter to find one account.
  • Profile panel — click a profile to open it. The panel lists User Details, Identifiers (known IPs and user agents), Custom Data & Tags (everything you sent with sync) and Recent Activity across the organization's Tag Mode projects.
  • HTTP Events — the events table shows the profile email next to each event, and the event detail panel carries the same Custom Data & Tags section alongside the request. See HTTP Events.

In both panels, scalar attributes are listed as key-value pairs and array values are shown as tag chips, grouped under the key you sent them with.

Working example

A typical integration renders one call from the server-side session on every authenticated page:

<script>window._waf360={q:[],send:(w,c)=>window._waf360.q.push([w,c]),check:w=>window._waf360.q.push(["check",w])};</script>
<script id="waf360-tag" src="https://tag.waf360.com/tag/tag.js" data-license="YOUR_LICENSE_KEY" defer async></script>
<script>
  window._waf360.send("sync", {
    email: "{{ user.email }}",
    name: "{{ user.full_name }}",
    customer_id: "cus_{{ user.id }}",
    plan: "{{ user.plan }}",
    seats: {{ user.seats }},
    approved: {{ user.is_approved ? 'true' : 'false' }},
    signup_date: "{{ user.created_at|date('Y-m-d') }}",
    segments: [{{ user.segments|join(', ') }}]
  });
</script>

On a page where the visitor is anonymous, simply do not call sync — the profile keeps whatever it learned on earlier visits.

Notes and limits

  • Sampling. If your tag sets data-sample-rate below 1, data collection — including sync — is skipped on unsampled page views. Use data-sample-rate="1" (or omit it) on pages that send profile data.
  • Consent. The tag writes the __unis_uid first-party cookie and your sync payload is stored against it, so gate the call behind consent where your jurisdiction requires it.
  • Sensitive data. Never send passwords, payment details, government identifiers or health information. Send an opaque customer ID and keep the sensitive record in your own systems.
  • Volume. Keep payloads to the attributes you will actually filter or read — a few dozen keys, not an export of your CRM.
  • Retention. Profiles persist until the project is deleted; the underlying events they are built from are retained for 90 days.

Stay ahead of the publishing curve

Privacy, security, monetization, and performance insights. A few emails a month, no spam.

By subscribing you agree to our privacy policy.