first_name, last_name, avatar_url, timezone, locale, department, job_title, manager, and primary_phone. Email and role aren’t governed by field pinning.
email is ungoverned but not unprotected, because it is the address people log in with. Two rules apply to changing it on PUT /v2/users/{id}:
- If the user came from your directory, change their email in your identity provider. Serval rejects the write rather than let the next sync silently revert it.
- Two users in one organization cannot share an address, and deactivating a user does not release theirs. If the address you want is already taken, the error names the user holding it. Move that user to another address first, then retry.
- Change email by itself. A rename crosses the user database and login system, so Serval rejects requests that combine it with other profile changes.
- A user who belongs to multiple organizations can’t be renamed through this endpoint. Login identity is global, while the API caller is scoped to one organization.
department and job_title the same way as locale: list USER_PROFILE_FIELD_DEPARTMENT or USER_PROFILE_FIELD_JOB_TITLE in pinFields. Any department value you save joins the org’s set of department options automatically.
Who wins
Three classes of writer compete for a governed field. The highest-ranked writer that has touched the field owns it.
A pin protects a field from automation. It doesn’t protect it from directory sync: if your IdP supplies a value, change it in the IdP. It also doesn’t protect it from ingestion on a sync-locked field: an org admin can lock any governed field except
avatar_url to the user sync from the Users database settings, after which the synced value is read-only and the next sync replaces manual values.
Pinning depends on your token
Whether a write pins by default depends on how you authenticated:- User token: pins by default. A person editing their own profile owns that value.
- API key or worker token: doesn’t pin. Your write stays automation-class unless you ask for a pin explicitly.
locale looks identical to ingestion writing locale, so the next sync is free to replace it.
Pin a field
List the field inpinFields on PUT /v2/users/{id}:
A pinned field must be set in the same request. You can’t pin a value that’s already stored. Send the value and the pin together, so the request’s outcome doesn’t depend on state you can’t see.
avatar_urlcan’t be pinned. Avatars live under a predictable key that automation can overwrite in place, so a pin wouldn’t protect the image. Listing it returns400.managerpins through the relationship endpoints, not here. See Manager.
POST /v2/users accepts pinFields for the two fields you can seed there, first_name and last_name:
When your write doesn’t land
An API-key write to a field someone else owns doesn’t fail. Serval applies the rest of the update and tells you what it skipped:200. Check these arrays if your workflow depends on the write landing.
skippedPinnedFields: a person, or another deliberate edit, owns this field. SendpinFieldsto take ownership.skippedDirectoryLockedFields: your IdP supplies this field. Change it there. No API call can take it.skippedSyncLockedFields: your org locked this field to user ingestion and the sync supplies its value. Change it in the source system. No API call can take it.
- If you write the value a pin already holds, the request succeeds cleanly and the field isn’t reported as skipped. Re-asserting the current state is a no-op, not a conflict.
- A directory-locked or sync-locked field is always reported, even when your value matches. Serval checks the lock before comparing values.
phoneNumberhas no entry in these arrays yet. If it is sync-locked, the whole request fails with400instead of skipping it, so a workflow never gets a200for a phone that did not change.
Release a field
Releasing hands a field back to automation. The current value stays, but loses its protection, so the next sync may replace it.400, and an API-key release reports it in skippedDirectoryLockedFields or skippedSyncLockedFields.
Primary phone
SetphoneNumber through PUT /v2/users/{id}. The user has zero or one primary; extra numbers do not require a primary.
Use
USER_PROFILE_FIELD_PRIMARY_PHONE in pinFields or releaseFields. Pinning requires phoneNumber in the same request ("" counts; omitted/null does not). Releasing retains the current number. You cannot set and release it together. Directory ownership still wins over pins and releases.
Check skippedPinnedFields and skippedDirectoryLockedFields, then read the phone collection to confirm the result. Primary selection never grants login trust. Directory and connected-app replacement still follow their existing trust-retirement rules.
A phone number can belong to only one user in an organization. If connected-app ingestion supplies a primary phone that another user already owns, Serval skips that phone and publishes the remaining profile fields. The existing phone assignments stay unchanged. Direct phone edits still reject duplicate assignments.
The skipped value remains in the source data. Resolving the conflicting assignment alone doesn’t retry an unchanged profile; the phone is reconsidered when the source profile changes or the user is explicitly republished.
Extra phone numbers
Extra phone numbers are the non-primary numbers shown on a user’s profile. You can add multiple extras without changing the primary number. There is no fixed per-user count limit; each request adds one number. UsePOST /v2/users/{user_id}/phone-numbers with an organization-scoped API key that has users:manage:
label is optional. The response’s data contains the new assignment’s id, e164, label, isPrimary: false, and verifiedForMagicLinkLogin: false.
Use GET /v2/users/{user_id}/phone-numbers with an organization-scoped API key that has users:read to list current assignments. The response includes both primary and extra numbers; select extras where isPrimary is false. An empty collection returns data: [].
Use DELETE /v2/users/{user_id}/phone-numbers/{phone_number_id} with an organization-scoped API key that has users:manage to remove an extra. Pass the assignment’s id from the add or list response. To remove a primary number, first choose another primary or clear the designation through Update User, confirm the collection, then delete its assignment ID. A concurrent primary change can safely reject deletion. Delete returns 200 {}.
- Adding or removing extra numbers for a synthetic user returns
404. These endpoints support human users. - Invalid numbers return
400. - A number already assigned in the organization returns
409, including a duplicate on the same user. The same number can be assigned in separate organizations. - Missing or removed assignments, and assignments belonging to another user, return
404. - Removing a primary number returns
400without changing any assignments.
PATCH /v2/users/{user_id}/phone-numbers/{phone_number_id} with the same users:manage key to edit a primary or extra assignment’s label:
label leaves it unchanged; null or "" clears it. Other JSON types return 400. The response contains the assignment in data. Label editing preserves the number, primary designation, ownership and verification, including for pinned or directory-owned primaries. Missing, deleted, inactive, synthetic, foreign-organization or wrong-user targets return 404, including no-op requests.
Adding a number does not grant login trust or helpdesk verification. Removing and re-adding a number creates a new assignment ID with login trust disabled. Grant login trust separately through Set User Phone Login Trust, using an organization-scoped API key with users:manage.
Manager
manager is written through the relationship endpoints rather than PUT /v2/users/{id}, so its pin lives there too.
Assign a manager with POST /v2/user-relationships and pin the assignment:
DELETE /v2/user-relationships/{user_id}, passing pin as a query parameter. Pinning a delete pins the cleared state, so ingestion can’t re-assign the manager it thinks the user should have.
The same token defaults apply: user tokens pin, API keys don’t. Pass pin: false from a user token to assign a manager without taking ownership of the field.
To hand the manager field back to ingestion, release it through PUT /v2/users/{id}:
What’s next
Update User
Full request and response schema, including
pinFields and releaseFields.Create User Relationship
Assign a manager and pin the reporting line.
Connect your IdP
Directory sync outranks every pin. Fields your IdP supplies are changed there.
Databases field precedence
The equivalent model for Databases item types.

