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

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:

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)

Rescope to server [​](/content/docs/api/fhir/operations/user-rescope#rescope-to-server "Direct link to Rescope to server"/index.html)

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)