Skip to content

Define a profile field

A profile field is one named value EdgeKit works out for every user on the sites you pick, such as an account type, a membership level or whether someone holds a company seat. You write it as ordered rules over what EdgeKit already holds about the user. EdgeKit writes the result into each user’s profile under the field’s name, and a Paywall rule reads it as profile.<name>.

Profile fields, resolutions and aggregations are authored records, like features. Creating or editing one needs the Owner, Admin or Developer role, and it reaches users only after a deploy, which needs Owner or Admin. Every deploy starts a background rebuild of every profile in your organization, each profile separately. Until a user’s rebuild finishes, a Paywall rule reads their old value, or no value yet for a new field.

Identity › Audience › Profile has five tabs:

Tab What it lists
Fields Your profile fields, what each reads and its trust.
Resolutions Named picks of one item out of a collection, which fields project from.
Aggregations Named sets of items from a collection, which fields collect or count.
Available data Everything a field can read, with its type and trust, and EdgeKit’s own fields.
Streaming The streaming inputs declared for your organization. See Send your own scores.

Available data lists every path a field can read, called the input bundle. It is assembled for one user on one site at each rebuild, and a field reads nothing else.

  • One value per user: user.* (such as user.email_verified, user.created_at and user.state), site.id, user_site.* (the user’s attachment to the site: its status, and how and when they arrived) and read_at, the moment of the rebuild.
  • Traits: user.traits.<name> for each collected trait. A list trait reads as its value ids, and user.traits.<name>.label reads the labels.
  • Streaming inputs: streaming.<pipeline>.<field> for each declared streaming input.
  • Collections, which hold many items per user:
    • memberships: one item per grant the user holds on the site, their own or through a user organization, with membership.* paths such as membership.level, membership.is_current, membership.is_seat and membership.expires_at.
    • billing_accounts: one item per billing account linked to the user, with billing_account.* paths.

A collection’s item paths are readable only through a resolution or an aggregation.

EdgeKit’s floor is listed below the input bundle: access, _envelope and _profile_schema_version. These names are EdgeKit’s. A field can never be named after them, and EdgeKit writes access and _profile_schema_version last, after every field.

  1. Open Identity › Audience › Profile and, on Fields, select New field.
  2. Under Identity:
    • Name: the path the field writes in the profile. Lowercase, with hyphens or underscores, for example membership_level. A dotted name such as member.level writes a nested value. The first part of the name cannot be access, _envelope or the first part of an input path such as user or membership, the name cannot be _profile_schema_version, and one field cannot nest inside another.
    • Type: string, number, boolean, date, string[] or enum. Every value the field can write is checked against it.
    • Legal values, for an enum: the whole set the field may write.
    • Sites: the sites whose profiles get this field. Pick at least one.
    • Next deploy: a new field is Left out, so an urgent deploy carries no unfinished work. Select it to switch it to Included when the field is ready.
  3. Under What it resolves against, leave Source at Per-user paths only, or pick a resolution to make its collection’s item paths readable against the item it picked.
  4. Under Rules, add rules in order. Each rule has conditions (When, then Or when for the next rule) and a value it writes. The first rule whose conditions hold decides the value, and nothing below it runs. The value is one of:
    • A value you type, checked against the type. No answer writes null.
    • A bundle path, copied as it is.
    • One path of a set: one item path collected across an aggregation, as a string[], either one entry per item or each distinct value once.
    • How many in a set: the number of items in an aggregation, as a number.
  5. Set Everyone else: the value for a user no rule matches. It is required, so the field always has a value.
  6. Select Create. Nothing is saved until you do: until then the field exists only in your browser.

After it is created, the field has its own screen. Every edit there is saved to the draft as you make it. Include in deploy and Leave out of next deploy switch whether the next deploy carries it, and Review and deploy opens Delivery › Deployments › Versions. See Stage and deploy a change.

A resolution picks exactly one item out of a collection, by name, so that every field reading “the user’s membership” agrees on which one it is. For example, primary-membership might pick the user’s current membership with the highest rank.

  1. On Resolutions, select New resolution.
  2. Enter a Name: lowercase letters, digits and hyphens. Names are shared by every authored record, so it cannot repeat a feature’s or a field’s name.
  3. Pick the Collection.
  4. Under Filter, add conditions on the collection’s item paths, such as whether a membership is current. An item must pass every condition. When no item passes, the resolution’s item paths read as empty: a condition on one of them does not hold, and a value copied from one is null.
  5. Under Ranking, add steps, applied in order until one step separates two items. Each step is Rank by (then Then by) a path, How: max (highest first), min (lowest first) or order (a Ladder of values you list, earliest winning, with unlisted values last). A resolution needs at least one step. EdgeKit adds the item’s id as a final tiebreak, so the same user resolves the same way on every rebuild.
  6. Select Create.

A field then names the resolution as its Source.

An aggregation keeps every item of a collection that passes a filter, such as every billing account a user is linked to. A field collects one path across the set or counts it.

  1. On Aggregations, select New aggregation.
  2. Enter a Name, on the same terms as a resolution’s.
  3. Pick the Collection and add a Filter. An empty set is not an error: a field collecting it writes an empty list, and one counting it writes 0.
  4. Optionally add an Order. Without one, items keep the collection’s own id order, which is stable across rebuilds.
  5. Optionally set Keep at most, applied after the order. A limit needs an order: staging refuses one without.
  6. Select Create.

Each field shows a Trust level: the weakest of every path it reads, through its resolution and aggregations too. A field that reads one user-written trait is Unverified, whatever else it reads. The console warns about such a field; a deploy does not refuse it.

A field marked no forwarder reads the user’s erased flag, user.is_deleted. It stays in the profile and can be read by Paywall rules, but no integration may send it outside EdgeKit.

After the deploy, a Paywall feature on one of the field’s sites can read it as profile.<name> in a condition. A feature on a site the field does not cover cannot. The value is as of the user’s last rebuild.

When a signed-in user has no profile value yet, the condition that reads it does not hold, and nothing errors. An anonymous request never reads the profile.

Deleting a field, resolution or aggregation changes the draft. The deployed version keeps it until somebody stages and deploys.

  • Deleting a field: it stops being derived at the next deploy. Anything that reads it, such as a Paywall condition, is refused at staging until it is changed.
  • Deleting a resolution or an aggregation that a field reads makes staging refuse that field. Delete the fields or point them elsewhere first.

Staging checks every field before a deploy. The commonest refusals:

  • The name’s first part is access, _envelope or an input namespace, or the name is _profile_schema_version.
  • No Sites are picked.
  • An enum field has no Legal values, or a typed value does not match the type.
  • A rule has no conditions. Write that value as Everyone else instead.
  • A field reads a path that is not in Available data, or a collection’s item path without a resolution.
  • A field names a resolution or an aggregation that is not in the next deploy.
  • A field collects into a type other than string[], or counts into a type other than number.
  • A resolution has no ranking step, or an aggregation keeps a limited number of items with no order.

Each rebuild also checks every value the fields write against their declared types. A rebuild that fails the check writes nothing, and the user’s previous profile stays until a later rebuild succeeds.