# SCIM Patch Operations

SCIM Patch Operations aggregate a collection of operations on a target resource.

SCIM Patching is described in [RFC7644 Section 3.5.2.](https://datatracker.ietf.org/doc/html/rfc7644#section-3.5.2)

This guide covers basics and common use cases related to our Firstup users and user groups.

## Overview

In context of the Firstup API, a SCIM patch is a way of editing a Firstup platform user or a Firstup user group. These users and user groups are created using SCIM, therefore editing them requires certain operations.

### Operation

An operation is a way of adding, changing, replacing or removing data in a user's record or a user group, e.g. change a user's last name.

To perform an operation, you send it as an object in a `PATCH` endpoint request connected to the relevant user or user group ID.

Patch endpoint examples:

PATCH /SCIM/v2/users/{userid}
PATCH /SCIM/v2/Groups/{groupId}
An operation object has three properties:

| Property | Description |
|  --- | --- |
| `op` | The type of operation being performed: `add`, `replace`, `remove`. |
| `path` | The data that needs changing from the operation (e.g. `title`) |
| `value` | What you want the data to be changed to (e.g. `mrs`) |


Based on our example of replacing an existing user's title from Miss to Mrs, your patch operation request looks like:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "title",
      "value": "Mrs"
    }
  ]
}
```

**Note**: This example shows how to replacing a simple string (root-level property). Continue to read for information on replacing or adding objects, lists and lists of objects.

### Targeting Properties

Unlike the above example, not all properties are at the root level.


```
const examplePaths = [
  { "path": "title" },                             // Root-level property
  { "path": "name:familyName" },                   // Nested property
  { "path": "urn:SocialChorus:1.0:User:managerName" }, // User extension property
]
```

## Patching Strings

To add, replace or remove a string attribute, you must need to include an `op`, a `path` and a `value`.

### Replacing Strings

A user's nickname is a string attribute that does not belong to a list or object. To change this:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "nickName",
      "value": "Barry"
    }
  ]
}
```

### Adding strings

To add a nickname to an existing user, change the `op` to `add`:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "nickName",
      "value": "Barry"
    }
  ]
}
```

### Remove Strings

To remove a nickname from an existing user, change the `op` to `remove` and don't send a `value`:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "remove",
      "path": "nickName",
    }
  ]
}
```

### Strings Use Case

Change UserName
## Patching Lists

Targeting an attribute within a list (array) requires a filter:

* The list (array) attribute name comes first `"listExample"`
* The list attributes are then shown inside square brackets `"ListExample": ["item1", "item2"]`
* The SCIM filter expressed supported is equals to, which means you type in the exact value you need. Example, `eq \"valuehere\"` - the `eq` is equals to, `valuehere` is where you type in your required value.


Complex lists will then have a list of objects, like the `addresses` array. Objects appear in curly brackets `{objectExample}`

### Replacing a List Attribute

Adding the filter after the list property name targets the list attribute.

For example, replacing a misspelled street address within a user's full address. The list is `addresses` but the `stretAddress` is a propery within this list.

Address list example:


```
  "addresses": [
    {
      "streetAddress": "123 Kission St",
      "locality": "San Francisco",
      "region": "CA",
      "postalCode": "94105",
      "country": "US",
      "primary": false,
      "formatted": "123 Mission St, San Francisco, CA, 94105",
      "type": "work"
    }
  ]
```

To only replace the streetAddress property your patch looks like:


```
{
  "op": "replace",
  "path": "address[streetAddress eq \"123 Kission St\"].streetAddress",
  "value": "123 Mission St"
}
```

The `OP` (operation) is to change the `path` (the current data) to the entered `value` by yourself (the new data - here 123 Mission St).

SCIM does not support position-based operations, meaning we can't target the "first" address, or re-order addresses from within SCIM itself. Those types of operations would need to be handled on the client side followed by a value replacement.

### Removing List Attributes

To remove a list attribute, change the `op` from `replace` to `remove` and don't include any `value`:


```
{
  "op": "remove",
  "path": "address[streetAddress eq \"123 Mission St\"].streetAddress"
}
```

### Adding List Attributes

To add a list to an existing user or user group, your `op` is `add`, your `path` is the blank data field that exists in the user or user group schema (e.g. `members`), and your `value` is your list (e.g. a list of members you want adding).

For example, you want to add users to an existing user group:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "members",
      "value": [
        {
          "value": "user1"
        },
        {
          "value": "user2"
        },
        {
          "value": "user3"
        },
        {
          "value": "user4"
        },
        {
          "value": "user5"
        }
      ]
    }
  ]
}
```

### List Use Case

Change email
## Patching Objects

For properties within objects (nested property), SCIM Paths use a colon as a path separator.

This means if you have an item in an object you wish to change, add in a colon between the object name and the attribute within.

* The object (nested) attribute name comes first `"objectExample"`
* The nested object attributes are then shown inside curly brackets `"objectExample": {"item1", "item2"}`


### Replacing an Object Attribute

To change a user's last name, you need to change the `familyName` property within the `name` object:


```
  "name": {
    "givenName": "Jane",
    "familyName": "Doe"
  },
```

This example means your `path` needs to include both the `name` and `familyName` attributes. This looks like:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "name:familyName",
      "value": "NewLastName"
    }
  ]
}
```

### Removing an Object Attribute

To remove an object attribute, using the same example, change the `op` from `replace` to `remove` and don't send a `value`:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "remove",
      "path": "name:familyName"
    }
  ]
}
```

### Adding an Object

Adding an object requires you to add in the object as the `path`, and then list out any attributes in the `value`. For example:


```
{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "emails",
      "value": [
        {
          "value": "janedoe@email.com",
          "primary": true,
          "type": "work"
        }
      ]
    }
  ]
}
```

### Object Use Case

Change role
## Pathless Targeting

Including a `path` property is optional when replacing properties.

If the optional path property is omitted it is assumed the target is the entire resource, e.g., a SCIM User or Group.

In this case the value property's own property names will align with the resource.

For example, replace a user's `userName` with a `path`:


```
{
  "op": "replace", 
  "path": "displayName", 
  "value": "User McUser"
}
```

Or without a `path`:


```
{ 
  "op": "replace",
  "value": {
    "displayName":  "User McUser"
  }
}
```

**Note:** Pathless replace replaces the entire object. It is not a merge. Remove operations require a path. Removes are value-less operations.

## Use Cases

Here a list of use cases where we're using a patch operation to change specific user details:

* [Change user's name](/usermanagementapi/user-managing#change-user-names)
* [Change user's email address ](/usermanagementapi/user-managing#change-users-email-address)