Skip to content

Let users manage their account

A signed-in user can read and change their own details: their name and the traits they answer about themselves. They can also change their email address. Each route acts on the user whose session the request carries, and on nobody else.

All of these routes answer 404 not_found at an external_only site, where EdgeKit holds no session. Changing the email address also answers 404 at a dual site, where your own login owns the address. See Choose who signs users in.

GET /v1/id/user-details answers the user and the traits they set, for a preferences form to start from.

const response = await fetch('/edgekit/v1/id/user-details', {
credentials: 'include',
headers: { 'x-edgekit-site-id': 'site_example' },
});
const details = await response.json();
// { id, email, emailVerified, name, firstName, lastName, image, userTraits }
  • userTraits holds only the traits the user writes, never the ones your staff write. It is {} for a user who has answered nothing.
  • Values come back as stored. A list value your organization has since suppressed is still returned, but is missing from GET /v1/id/traits: show it as unset.
  • With no session the route answers 401 unauthorized. A session whose user no longer exists answers 404 not_found.

The browser client’s call is id.getUserDetails.

PATCH /v1/id/user-details writes the fields you send and answers the user as GET does. Send at least one field.

Terminal window
curl -X PATCH https://your-tenant-host/v1/id/user-details \
-H 'x-edgekit-site-id: site_example' \
-H 'Authorization: Bearer <session-token>' \
-H 'content-type: application/json' \
-d '{"firstName": "Ada", "userTraits": {"job_industry": "01926f3a-8b51-7e99-9aaa-8b9c0d1e2f3a", "newsletter_note": null}}'
Field What it does
name The display name, 1 to 200 characters. It cannot be cleared.
firstName 1 to 100 characters. null clears it.
lastName 1 to 100 characters. null clears it.
userTraits A patch: each key you send replaces that trait’s value, null deletes it, and a trait you leave out keeps its value.

The traits are checked after the patch is merged, so a one-key patch is not refused for another trait the user has already answered. A required trait the user has never answered refuses every userTraits patch until one answers it. A list trait’s value is the id of one of its values. A value your organization has suppressed is accepted and dropped, not refused, because your page may have read the list before the change.

The same body writes the same values, so a retry is safe. The browser client’s call is id.updateUserDetails.

Status Code Message Cause
401 unauthorized No user session. The request carries no session.
422 unprocessable_entity Request validation failed. No field sent, or a field out of its bounds.
422 unprocessable_entity User traits failed validation. A trait value fails its check. details names the trait and the reason.

The email address is not a field here. It changes only through the two steps below.

Changing the address takes two requests, so that the user proves they hold the new one. This works at an edgekit_only site only.

  1. Request a code for the new address. EdgeKit emails a 6-digit code to it and answers 200, whether or not another user holds the address, so the route never tells anyone which addresses exist. A new request replaces the code still outstanding, and counts against the new address’s sign-in email limit.

    Terminal window
    curl -X POST https://your-tenant-host/v1/id/change-identifier/request \
    -H 'x-edgekit-site-id: site_example' \
    -H 'Authorization: Bearer <session-token>' \
    -H 'content-type: application/json' \
    -d '{"newEmail": "ada.l@example.com"}'
  2. Confirm with the address and the code the user typed.

    Terminal window
    curl -X POST https://your-tenant-host/v1/id/change-identifier/confirm \
    -H 'x-edgekit-site-id: site_example' \
    -H 'Authorization: Bearer <session-token>' \
    -H 'content-type: application/json' \
    -d '{"newEmail": "ada.l@example.com", "otp": "482913"}'

On success the address moves, verified, and every session the user holds ends, this one included: send the user back through sign-in. The user id, their grants and their memberships do not change. A confirmed change cannot be retried: the code is spent and the session is gone.

Status Code Message Cause
400 bad_request That code is not valid. The code is wrong or expired, or no change is pending for that address.
409 conflict That address is already in use. Another user holds the address. Two users are never merged.
429 too_many_requests Too many attempts. Request a new code. Three wrong guesses at this code.
429 too_many_requests Too many sign-in emails for this address. Try again in a minute. The send limit for the new address.

The browser client’s calls are id.changeIdentifier.request and id.changeIdentifier.confirm. At a dual or external_only site your server tells EdgeKit about an address change instead; see Tell EdgeKit about changes in your login.

Staff can correct an address from the console, with different results: see Correct a user’s email address.