User $rescope | Medplum
On this page
The $rescope operation moves a User between server scope (not owned by any Project) and project scope (owned by a specific Project). This controls which Project the User resource itself belongs to — it is distinct from a ProjectMembership, which controls access.
See Project vs Server Scoped Users for background on how scoping works.
POST [base]/User/[id]/$rescope
Privileged Operation
- Rescoping to project scope requires Super Admin privileges.
- Rescoping to server scope requires Super Admin or Project Admin privileges (project admins may only release users belonging to their own project).
Irreversibility for Project Admins
A project admin who releases a user to server scope cannot reverse the change — only a super admin can re-assign a server-scoped user to a project. Confirm the action before proceeding.
App UI [](/content/docs/api/fhir/operations/user-rescope#app-ui "Direct link to App UI"/index.html)
Two widgets in the Medplum App invoke this operation:
- Project Admin Config — available to project admins and super admins at
https://app.medplum.com/admin/config. Allows releasing a project-scoped user to server scope. Super admins can also assign server-scoped users to a project from this page. - Super Admin Panel — available to super admins at
https://app.medplum.com/admin/super. Provides the same Rescope User widget with full cross-project visibility.
Parameters [](/content/docs/api/fhir/operations/user-rescope#parameters "Direct link to Parameters"/index.html)
The input is a FHIR Parameters resource:
| Parameter | Type | Required | Description |
|---|---|---|---|
scope |
code |
Yes | Target scope: "project" or "server" |
project |
Reference(Project) |
Conditional | Required when scope is "project". The Project the user will be scoped to. |
Output [](/content/docs/api/fhir/operations/user-rescope#output "Direct link to Output"/index.html)
Returns the updated User resource with User.project set (project scope) or cleared (server scope).
Examples [](/content/docs/api/fhir/operations/user-rescope#examples "Direct link to Examples"/index.html)
Release a user to server scope [](/content/docs/api/fhir/operations/user-rescope#release-a-user-to-server-scope "Direct link to Release a user to server scope"/index.html)
TypeScript:
await medplum.post(`fhir/R4/User/${userId}/$rescope`, {
resourceType: 'Parameters',
parameter: [
{ name: 'scope', valueCode: 'server' },
],
});
cURL:
curl -X POST 'https://api.medplum.com/fhir/R4/User/example-user-id/$rescope' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{ "name": "scope", "valueCode": "server" }
]
}'
Assign a user to a project (super admin only)
TypeScript:
await medplum.post(`fhir/R4/User/${userId}/$rescope`, {
resourceType: 'Parameters',
parameter: [
{ name: 'scope', valueCode: 'project' },
{ name: 'project', valueReference: { reference: `Project/${projectId}` } },
],
});
cURL:
curl -X POST 'https://api.medplum.com/fhir/R4/User/example-user-id/$rescope' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/fhir+json" \
-d '{
"resourceType": "Parameters",
"parameter": [
{ "name": "scope", "valueCode": "project" },
{ "name": "project", "valueReference": { "reference": "Project/example-project-id" } }
]
}'
Response (200 OK):
{
"resourceType": "User",
"id": "example-user-id",
"email": "alice@example.com",
"firstName": "Alice",
"lastName": "Smith",
"project": {
"reference": "Project/example-project-id",
"display": "My Project"
}
}
Behavior [](/content/docs/api/fhir/operations/user-rescope#behavior "Direct link to Behavior"/index.html)
Rescope to project [](/content/docs/api/fhir/operations/user-rescope#rescope-to-project "Direct link to Rescope to project"/index.html)
- Requires the target
Projectto exist. - Rejects if the user is already scoped to the specified project.
- Rejects if the user holds a
ProjectMembershipin any other project — remove those memberships before rescoping. - Sets
User.projectto the target project reference. - Runs inside a serializable transaction to prevent race conditions with concurrent membership changes.
Rescope to server [](/content/docs/api/fhir/operations/user-rescope#rescope-to-server "Direct link to Rescope to server"/index.html)
- Rejects if the user is already server-scoped.
- Clears
User.projectfrom the user resource. - Existing
ProjectMembershipresources are left in place; clean them up separately if needed.
Error Responses [](/content/docs/api/fhir/operations/user-rescope#error-responses "Direct link to Error Responses"/index.html)
| Status | Description |
|---|---|
200 OK |
Rescope successful — returns the updated User |
400 Bad Request |
Invalid scope value; missing project when scope is "project"; user already in the target scope; or user holds memberships in another project |
403 Forbidden |
Caller lacks sufficient privileges, or project admin attempted to rescope a user from a different project |
404 Not Found |
User or target project not found |
See Also [](/content/docs/api/fhir/operations/user-rescope#see-also "Direct link to See Also"/index.html)
- Project vs Server Scoped Users
- User Management Guide
- User $update-email — update a user's email address
- User Resource
- ProjectMembership Resource