Skip to content

Profile FAQ

Does a user have one profile, or one per site?

Section titled “Does a user have one profile, or one per site?”

One per site they are attached to: the site they registered on, and any site they bought on, joined a newsletter list on or signed in on through your identity provider. They are still one user, with one set of details and trait answers. A device, the state of an anonymous browser, has no profile. See One user across your sites.

What is the difference between a user’s details, their trait answers and their profile?

Section titled “What is the difference between a user’s details, their trait answers and their profile?”
  • Details are what the person wrote about themselves: name, email address and their answers to the traits they write. One set per user. The user edits their names and answers with PATCH /v1/id/user-details.
  • Traits are the questions you declare in Identity › Audience › Traits.
  • The profile is what EdgeKit derives for the user on each site, from their details, their grants, their billing accounts and their streaming inputs. Nobody edits it: every rebuild replaces it.

Can I rename a trait, or change its type or who writes it?

Section titled “Can I rename a trait, or change its type or who writes it?”

No. The name is the key on every user’s record and the path a profile field reads, and changing the type or the writer would leave every stored answer invalid or unread. Only the label, the default value, Allow more than one value and Required at sign-up can change. To fix the name, type or writer, delete the trait and declare it again, which works only while nothing reads it.

A profile field, resolution or aggregation reads it, enabled or not. The refusal and the trait’s Read by section name each one. Edit or delete them first. Suppressing a trait that records read would make your next staging fail.

Why could a user sign up without answering a required trait?

Section titled “Why could a user sign up without answering a required trait?”

One of three reasons:

  • The sign-up request sent no userTraits at all. Only a request that sends userTraits is checked.
  • The user signed up with a magic link or with Google, which carry no trait answers.
  • The trait was made required after they signed up.

A Paywall rule can find such users with db_user_traits.complete, which is false while any collected, required trait has no answer, and send them to your preferences screen. It is read on decide requests from your server and on journey redirects, never on a decide request from the browser; see Facts.

Section titled “How do users who signed up with Google or a magic link answer my traits?”

On a screen of yours after they sign in. Render it from GET /v1/id/traits and save with PATCH /v1/id/user-details. See Let users manage their account.

No. A PATCH /v1/id/user-details that names it is refused with 422. Such a trait is never listed by GET /v1/id/traits, never asked at sign-up, and never returned to the user.

How do my staff fill in a trait they write?

Section titled “How do my staff fill in a trait they write?”

They cannot: no console screen or API request writes a staff-written trait’s value, so it reads as empty for every user. To bring values from your own systems into the profile, send them as a streaming input, which profile fields and Paywall rules read at Computed trust.

Can I send scores from my own model, such as a churn score?

Section titled “Can I send scores from my own model, such as a churn score?”

Yes, as a streaming input: EdgeKit declares a pipeline with your organization as its source, and your server sends batches with an API key holding streaming:write. Not as a trait: a staff-written trait has no writer. See Send your own scores.

What happens to stored answers when I suppress a value?

Section titled “What happens to stored answers when I suppress a value?”

They stay on users’ records. GET /v1/id/user-details still returns the value’s id, so render an id that GET /v1/id/traits no longer lists as unanswered. A profile field reading the trait sees the trait’s default value instead, or no value when there is no default. A user who sends the suppressed value is accepted, and the value is dropped.

I changed Allow more than one value. Why do users’ saves fail?

Section titled “I changed Allow more than one value. Why do users’ saves fail?”

Users who answered before the change hold an answer in the old shape: a single value where the trait now expects a list, or the reverse. EdgeKit checks the whole merged record on every save of trait answers, so those users get 422 on any save that names a trait, until a request replaces or clears that answer. A save that changes only their name still works. Have your preferences screen send the trait in its new shape.

Why is a save refused for a trait the request did not name?

Section titled “Why is a save refused for a trait the request did not name?”

EdgeKit checks the user’s whole record after merging the request, not only the keys sent. The record still fails when:

  • a required trait has no answer;
  • a stored answer names a list value you deleted;
  • a stored answer has the wrong shape after you changed Allow more than one value.

error.details names the trait. Send that trait’s answer in the same request to fix it.

No. A feature’s conditions cannot name user.traits.<name>. Define a profile field that reads the trait, deploy, and read the field as profile.<name>. The one trait fact a rule can read is db_user_traits.complete.

How much should a rule trust a trait answer?

Section titled “How much should a rule trust a trait answer?”

As much as anything a user types about themselves. A profile field that reads a user-written trait is Unverified, whatever else it reads, and the console warns about it. A staff-written trait and a streaming input are Computed. Access itself never comes from the profile: it is read live from the user’s grants.

No. What is public, through GET /v1/id/config and GET /v1/id/traits, is the questions: each collected, user-written trait’s name, label, type and whether it is required, and each offered list value’s id, label and external ID. A user’s answers are returned only to that user, by GET /v1/id/user-details, and no session payload carries them.

When their details or trait answers change, when one of their grants changes, when a billing account linked to them syncs, when they are attached to a site, and when a streaming input for them arrives. Every deploy rebuilds every profile in your organization.

Why does a profile value look out of date?

Section titled “Why does a profile value look out of date?”

A profile is computed when it is rebuilt, and some changes do not rebuild it:

  • Time passing. A grant reaching its end date writes nothing, so access.expiresInDays and any field that reads membership.is_current or read_at keep their values from the last rebuild.
  • User organizations. Joining or leaving a user organization, and renaming one, do not rebuild the members’ profiles.

The profile catches up at the user’s next rebuild: their next change, a change to one of their grants, or your next deploy.

There is no action that rebuilds one user’s profile. Every deploy rebuilds every profile in your organization.

A rebuild whose fields fail their checks writes nothing, and the user’s previous profile stays. Nothing retries it: the profile is rebuilt at the next change that triggers a rebuild, or at your next deploy.

No. Identity › Audience › Users shows each site’s profile read-only. Every rebuild replaces the whole document, so change the profile field and deploy instead.

Can a profile field read events, page views or read counts?

Section titled “Can a profile field read events, page views or read counts?”

No. A profile field reads only the input bundle listed on Available data: the user’s details and trait answers, their site attachment, their grants and billing accounts, and their streaming inputs. Behaviour reaches the profile only already worked out, as a streaming input.

What does a Paywall rule do when a user’s profile is late or missing?

Section titled “What does a Paywall rule do when a user’s profile is late or missing?”

The condition that reads the missing value does not hold, and it never sends the request to the error outcome. No rule can read the profile’s access fields: access comes from the user’s grants, read live, so a grant counts in decisions without waiting for a rebuild.

Does the profile reach my warehouse or marketing platform?

Section titled “Does the profile reach my warehouse or marketing platform?”

No. Both receive events. Your warehouse is loaded from EdgeKit’s archive of events and nothing else, and a marketing platform connected for forwarding receives the events that carry a user id, under that id. Neither receives the profile document or trait answers.

The one integration that can receive profile fields is a recommendations integration, and only the fields its configuration names. A field marked no forwarder, because it reads the user’s erased flag, is never sent by any integration.

Is there an API to read a user’s profile?

Section titled “Is there an API to read a user’s profile?”

No. The user reads their own details and trait answers with GET /v1/id/user-details. Profile fields are read by Paywall rules, as profile.<name>, and shown in Identity › Audience › Users.

What happens to a user’s profile and trait answers when they are erased?

Section titled “What happens to a user’s profile and trait answers when they are erased?”

Their own trait answers are cleared, and values of staff-written traits are kept. Every profile of theirs is deleted and is never rebuilt, and their streaming values are deleted and later ones refused. How to erase a user, and what else changes on their record, is in the users FAQ.

Nowhere on the user. EdgeKit records consent as events: each event carries your declared consent basis, and your page can attach a consent_document entity to record what the user agreed to. See Record consent.

No. Your consent management platform runs the consent screen. Create the tracker with requireConsent: true and call grantConsent() and revokeConsent() from it.

Section titled “Does the collector drop events from users who did not consent?”

No. The collector accepts every event and never checks consent. Holding events until consent is the tracker’s job, on your page.

Not through EdgeKit’s events. With requireConsent, nothing is sent before grantConsent(), so a user who declined sends no events, and looks the same as a page with no tracker.