# ServiceUserRole

A *ServiceUserRole* is a bundle of permissions you grant to an end-user who signed up for your product, that is, a *ServiceUser*. It holds in one resource what they can do (read, create, edit, delete) to *Content Type*s, *Content*, and *Media*, whether they can execute a *Script*, along with filters that narrow the scope, such as only certain *Content Type*s or only what they created. The actions you can use differ from map to map (see the [Permission maps](#permission-maps-contenttype-content-media) table below). These permissions apply to the ACMA/ACDA that the *ServiceUser* calls.

It sits in a different place from a *SpaceRole*. A *SpaceRole* is a bundle of permissions for a Weegloo User (a content studio user) and applies to CMA/CDA, while a *ServiceUserRole* is a bundle of permissions for a *ServiceUser* who signed up for your product and applies to ACMA/ACDA. A *ServiceUserRole* you create applies to nobody on its own. You grant it by setting it as the default role (`defaultRole`) on a [ServiceLogin](/api/reference/cma/service-login.md), or by binding it to the `roleOverride` of a [ServiceUser](/api/reference/cma/service-user.md).

## Resource structure {#resource-structure}

The following is the single-read response for the *ServiceUserRole* "Buyer". Together with `sys` (system properties), it has the body properties that define permissions: `contentType`, `content`, `media`, and `script`.

```json
{
  "sys": {
    "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
    "type": "ServiceUserRole",
    "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-18T12:40:36.944Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-18T12:40:36.944Z",
    "version": 1
  },
  "name": "Buyer",
  "description": "Member who can read published products",
  "contentType": { "All": { "Allow": [] } },
  "content": {
    "Read": {
      "Allow": [
        { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
      ]
    }
  },
  "media": { "All": { "Allow": [] } },
  "script": {}
}
```

Key properties:

- `contentType`: The permission map for *Content Type*s themselves (the schema). A *ServiceUser* only reads the form, so you set `Read` alone.
- `content`: The permission map for *Content* (the content data). The example above limits the role to reading only the *Content* of one specific *Content Type*.
- `media`: The permission map for *Media* (files and images).
- `script`: The permission map for *Script* (declarative backend endpoints). A *ServiceUser* only executes (`Execute`) a *Script*.

Unlike a *SpaceRole*, a *ServiceUserRole* has no `settings` to hold access to *Space* settings, because a *ServiceUser* does not work with *Space* settings. It also has no `sys.isLocked` to mark whether the role is provided by default.

## System properties (sys) {#system-properties-sys}

Every *ServiceUserRole* carries common system properties in the `sys` object. `space`, `createdBy`, and `updatedBy` are in the `Refer` shape (`{ "sys": { "id", "type": "Refer", "targetType" } }`).

| Property | Type | Description |
|---|---|---|
| `id` | string | Unique resource identifier. |
| `type` | string | Resource kind. For a *ServiceUserRole* this is always `"ServiceUserRole"`. |
| `space` | Refer&lt;Space&gt; | The *Space* this *ServiceUserRole* belongs to. |
| `createdBy` | Refer&lt;User&gt; | The user who created it. |
| `createdAt` | string (date-time) | Creation time. |
| `updatedBy` | Refer&lt;User&gt; | The user who last updated it. |
| `updatedAt` | string (date-time) | Last update time. |
| `version` | integer (≥1) | Resource version. It increases by 1 with every change. |

A *ServiceUserRole* is a settings resource with no publishing concept. So unlike *Content* and *Media*, its `sys` has no `publish`, `archive`, or `status`, only `version`. The `version` increases each time you update the *ServiceUserRole*. Unlike a *SpaceRole*, it also has no `sys.isLocked`.

## Permission maps: contentType, content, media {#permission-maps-contenttype-content-media}

`contentType`, `content`, `media`, and `script` are each a **map keyed by action**. The value of each action is an object holding `Allow` and `Deny` arrays of rules. The structure of the maps is the same as a *SpaceRole*, but **the actions you can use differ from map to map and are narrower than on a *SpaceRole*.**

| Permission map | Actions you can use |
|---|---|
| `contentType` | `All`, `Read` |
| `content` | `All`, `Create`, `Read`, `Edit`, `Delete` |
| `media` | `All`, `Create`, `Read`, `Delete` |
| `script` | `All`, `Execute` |

`All` refers at once to every action you can use in that map. If you put in an action the table does not list, saving the role is rejected. None of the maps carry the publishing actions (`Publish`, `Unpublish`, `Archive`, `Unarchive`) because *Content* and *Media* a member creates are published the moment they are created (see [ACMA](/api/reference/acma.md#differences-from-cma)).

**There is no action called `Save`.** The permission to modify is `Edit`, and `Save` is the name of an event a [Webhook](/api/reference/cma/webhook.md#topics) subscribes to.

```json
"content": {
  "Read":   { "Allow": [ /* rule */ ], "Deny": [ /* rule */ ] },
  "Edit":   { "Allow": [ /* rule */ ] }
}
```

Each rule object has optional filters that narrow the permission's scope.

- `self`: Limits the target the rule applies to the **resource itself**, one single resource. In the `contentType` map it means one specific *Content Type*; in the `script` map, one specific *Script*.
- `contentType`: Limits to the *Content Type* the *Content* **belongs to**. You put in a `Refer` that points to a *Content Type*.
- `createdBy`: Limits to only resources created by a specific user. Put a specific user id in `sys.id` to limit to what that person created, or the reserved value `:self` to limit to "only what the *ServiceUser* making the current call created".
- `tag`: Limits to only resources carrying a specific *Tag*.

Which filter is valid in which permission map is the same as for a *SpaceRole* (the `contentType` map names its target with `self`, and the `content` map with `contentType`), and putting in a filter that does not fit makes saving the role fail. The per-map table is in [Permission maps on SpaceRole](/api/reference/cma/space-role.md#permission-maps-contenttype-content-media).

> **To apply a `createdBy` filter (including `:self`) on ACDA, the target *Content Type*'s `publishWithAuthor` must be `true`.** ACDA evaluates this filter against the `sys.createdBy` of the publish snapshot, so if `publishWithAuthor` is left at its default `false` the snapshot has no author: an `Allow` rule matches nothing (a member receives their own resources as an empty result), and a `Deny` rule filters out no one. ACMA (management), on the other hand, evaluates against the `sys.createdBy` of the draft and is therefore independent of this setting, so the same rule may work on ACMA yet break on ACDA. `publishWithAuthor` must be turned on before members start posting, and it is not retroactive. See the `publishWithAuthor` description in [Content Type](/api/reference/cma/content-type.md).

**An empty `Allow` array `[]` means the action is allowed across the entire kind.** Because the filter is empty there is nothing to filter out, so the action is open to all resources.

Unlike a *SpaceRole*, a *ServiceUserRole* has no `settings`. The permission maps are the four: `contentType`, `content`, `media`, and `script`. For how to write the permission maps, including the filter keys and the meaning of `:self`, see also the explanation in [SpaceRole](/api/reference/cma/space-role.md), which uses the same structure. Note, however, that **the actions you can use are the ones in the table above, and they differ from a *SpaceRole*.** [Regular member roles and administrator roles](#admin-role), just below, shows an example that uses `:self` to narrow editing to only the *Content* the caller created.

> The filter keys (`self`, `contentType`, `createdBy`, `tag`) and the meaning of `:self` follow the permission-rule definition in [SpaceRole](/api/reference/cma/space-role.md#permission-maps-contenttype-content-media). For a *ServiceUserRole*, `:self` resolves to only what the current *ServiceUser* created. The action list does not follow *SpaceRole*; it follows the table above.

### Regular member roles and administrator roles {#admin-role}

Whether a member can handle other members' resources is decided by the rule's `createdBy` filter. For one and the same action, putting `:self` in `createdBy` makes that action target only what the calling member created, while leaving `createdBy` out makes it target what other members created as well.

The role you give to regular members limits `Edit` and `Delete` with `:self`.

```json
"content": {
  "Edit": {
    "Allow": [
      {
        "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
        "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
      }
    ]
  },
  "Delete": {
    "Allow": [
      {
        "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
        "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
      }
    ]
  }
}
```

For a member who is to act as an administrator, build a separate role that drops `createdBy` from the same action. The role below opens only deleting to other members' items and leaves editing limited to the member's own.

```json
"content": {
  "Edit": {
    "Allow": [
      {
        "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } },
        "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } }
      }
    ]
  },
  "Delete": {
    "Allow": [
      { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
    ]
  }
}
```

You apply a role built this way to one member alone by setting it on that [ServiceUser](/api/reference/cma/service-user.md)'s `roleOverride`. If you leave *ServiceLogin*'s `defaultRole` as the regular member role, a member who newly signs up does not receive the administrator role.

*Media* works the same way. Dropping `createdBy` from an action in the `media` map makes it target files other members uploaded as well. Note that the `contentType` filter is used only in the `content` map, so do not put it in the `media` map.

### script (Script permissions) {#script-permission}

`script` is the permission map for *Script*; its structure is the same as `content` and `media`. However, the only thing a *ServiceUser* can do to a *Script* is **execute** it (authoring, that is create/edit/delete, is CMA / Weegloo-User only). So the only actions you can use in a *ServiceUserRole*'s `script` are the two `All` and `Execute`.

To let a signed-up member execute a *Script*:

```json
"script": {
  "Execute": { "Allow": [] }
}
```

The rule filters you can use are two: `self` (one specific *Script*) and `createdBy`. `contentType` and `tag` are axes that do not attach to *Script*, so putting them in makes saving the role fail. To let a member execute one specific *Script* and nothing else, put a `self` rule pointing at that *Script* in the `Allow` of `Execute`.

```json
"script": {
  "Execute": {
    "Allow": [
      { "self": { "sys": { "id": "3trmXRMZcTAjDnphewjj1AaxYcaxlK", "type": "Refer", "targetType": "Script" } } }
    ]
  }
}
```

The structure of *Script* itself and its execute endpoint are covered in [Script resource and endpoints](/api/reference/script/endpoints.md); the full action list is covered in [the script permission on SpaceRole](/api/reference/cma/space-role.md#script-permission).

## Errors {#errors}

These are the codes you meet when working with a *ServiceUserRole*. For codes that are common to every resource, see [common errors](/api/reference/common/errors.md).

| Code | Condition |
|---|---|
| `WGL400020` | A rule put a filter into a permission map that cannot use that filter, so saving the *ServiceUserRole* was rejected. Putting `contentType` or `tag` into the `script` map is one such case. |

## API {#api}

The base URL for all endpoints below is `https://cma.weegloo.com/v1`, and a Bearer token that authenticates against CMA is required in the `Authorization` header. Role updates (`PUT`, `PATCH`) must also send the `X-Weegloo-Version` header (the current resource's `sys.version`) for optimistic concurrency control. Create and delete do not have this header.

```api-endpoint
{
  "title": "List ServiceUserRoles",
  "method": "GET",
  "path": "/spaces/{spaceId}/service-user-roles",
  "description": "Reads the ServiceUserRoles of one Space, page by page.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "queryParameterSchema": {
    "limit": { "type": "integer", "description": "Number of items to return per page (1-100)", "default": 15 },
    "skip": { "type": "integer", "description": "Number of items to skip", "default": 0 },
    "next": { "type": "string", "description": "Next-page cursor (the value from links.next in the previous response)" },
    "prev": { "type": "string", "description": "Previous-page cursor (the value from links.prev in the previous response)" },
    "order": { "type": "string", "description": "Sort criteria. Multiple sorts separated by commas (e.g. sys.createdAt,sys.id)", "default": "sys.createdAt,sys.id" },
    "select": { "type": "string", "description": "Fields to include (sys.id,sys.createdAt) or exclude (-sys.id). Do not mix inclusion and exclusion." },
    "include": { "type": "integer", "description": "Related-resource inclusion level. 0=default, 1=related resources, 2=nested relations, 3=full", "default": 0 }
  },
  "additionalQueryParams": true,
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "responseExample": {
    "sys": { "type": "TotalPageResponse" },
    "limit": 15,
    "totalCount": 1,
    "items": [
      {
        "sys": {
          "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
          "type": "ServiceUserRole",
          "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
          "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
          "createdAt": "2026-06-18T12:40:36.944Z",
          "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
          "updatedAt": "2026-06-18T12:40:36.944Z",
          "version": 1
        },
        "name": "Buyer",
        "description": "Member who can read published products",
        "contentType": { "All": { "Allow": [] } },
        "content": {
          "Read": {
            "Allow": [
              { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
            ]
          }
        },
        "media": { "All": { "Allow": [] } },
        "script": {}
      }
    ],
    "links": { "self": "/v1/spaces/tcq4V2Xb/service-user-roles" }
  }
}
```

```api-endpoint
{
  "title": "Read a single ServiceUserRole",
  "method": "GET",
  "path": "/spaces/{spaceId}/service-user-roles/{roleId}",
  "description": "Reads one ServiceUserRole by sys.id.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "roleId": { "type": "string", "description": "The sys.id of the ServiceUserRole", "required": true }
  },
  "queryParameterSchema": {
    "include": { "type": "integer", "description": "Related-resource inclusion level. 0=default, 1=related resources, 2=nested relations, 3=full", "default": 0 }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
      "type": "ServiceUserRole",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:40:36.944Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:40:36.944Z",
      "version": 1
    },
    "name": "Buyer",
    "description": "Member who can read published products",
    "contentType": { "All": { "Allow": [] } },
    "content": {
      "Read": {
        "Allow": [
          { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
        ]
      }
    },
    "media": { "All": { "Allow": [] } },
    "script": {}
  }
}
```

```api-endpoint
{
  "title": "Create a ServiceUserRole",
  "method": "POST",
  "path": "/spaces/{spaceId}/service-user-roles",
  "description": "Creates a new ServiceUserRole in one Space. The body holds name and the contentType/content/media permission maps. Apply it by binding the sys.id in the response to a ServiceLogin's defaultRole or a ServiceUser's roleOverride.",
  "responseStatus": 201,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "contentType", "content", "media", "script"],
    "properties": {
      "name": { "type": "string", "description": "Role name" },
      "description": { "type": "string", "description": "Role description (optional)" },
      "contentType": { "type": "object", "description": "Permission map for Content Types. The actions are only All/Read. Keyed by action, with { Allow, Deny } rule arrays as values. An empty Allow array allows everything." },
      "content": { "type": "object", "description": "Permission map for Content. The actions are All/Create/Read/Edit/Delete. Rules narrow scope with contentType/createdBy/tag filters." },
      "media": { "type": "object", "description": "Permission map for Media. The actions are All/Create/Read/Delete, with no Edit." },
      "script": { "type": "object", "description": "The permission map for Script. The actions are only All/Execute. Send an empty object even when you grant no execute permission." }
    },
    "example": {
      "name": "Buyer",
      "description": "Member who can read published products",
      "contentType": { "All": { "Allow": [] } },
      "content": {
        "Read": {
          "Allow": [
            { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
          ]
        }
      },
      "media": { "All": { "Allow": [] } },
      "script": {}
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
      "type": "ServiceUserRole",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:40:36.944Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:40:36.944Z",
      "version": 1
    },
    "name": "Buyer",
    "description": "Member who can read published products",
    "contentType": { "All": { "Allow": [] } },
    "content": {
      "Read": {
        "Allow": [
          { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
        ]
      }
    },
    "media": { "All": { "Allow": [] } },
    "script": {}
  }
}
```

```api-endpoint
{
  "title": "Update a ServiceUserRole",
  "method": "PUT",
  "path": "/spaces/{spaceId}/service-user-roles/{roleId}",
  "description": "Replaces the whole ServiceUserRole. The body holds name and the full permission maps. The example below sets createdBy to :self in the content Edit rule to narrow it to 'edit only the Content the caller created'. :self limits to only what the current ServiceUser created. You must carry the current sys.version in the X-Weegloo-Version header.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "roleId": { "type": "string", "description": "The sys.id of the ServiceUserRole", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "X-Weegloo-Version": { "type": "integer", "description": "The current resource's sys.version (optimistic concurrency control)" }
  },
  "requestBodySchema": {
    "type": "object",
    "required": ["name", "contentType", "content", "media"],
    "properties": {
      "name": { "type": "string", "description": "Role name" },
      "description": { "type": "string", "description": "Role description (optional)" },
      "contentType": { "type": "object", "description": "Permission map for Content Types. The actions are only All/Read." },
      "content": { "type": "object", "description": "Permission map for Content. Put :self in createdBy.sys.id to limit to only what the current ServiceUser created." },
      "media": { "type": "object", "description": "Permission map for Media. The actions are All/Create/Read/Delete, with no Edit." },
      "script": { "type": "object", "description": "The permission map for Script. The actions are only All/Execute. Optional." }
    },
    "example": {
      "name": "Buyer",
      "description": "Read published products and write own reviews",
      "contentType": { "All": { "Allow": [] } },
      "content": {
        "Read": {
          "Allow": [
            { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
          ]
        },
        "Edit": {
          "Allow": [
            { "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } } }
          ]
        }
      },
      "media": { "All": { "Allow": [] } },
      "script": {}
    }
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
      "type": "ServiceUserRole",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:40:36.944Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:40:50.000Z",
      "version": 2
    },
    "name": "Buyer",
    "description": "Read published products and write own reviews",
    "contentType": { "All": { "Allow": [] } },
    "content": {
      "Read": {
        "Allow": [
          { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
        ]
      },
      "Edit": {
        "Allow": [
          { "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } } }
        ]
      }
    },
    "media": { "All": { "Allow": [] } },
    "script": {}
  }
}
```

```api-endpoint
{
  "title": "Partially update a ServiceUserRole (JSON Patch)",
  "method": "PATCH",
  "path": "/spaces/{spaceId}/service-user-roles/{roleId}",
  "description": "Updates only part of a ServiceUserRole with RFC 6902 JSON Patch. The request Content-Type header must be application/json-patch+json. You must carry the current sys.version in the X-Weegloo-Version header.",
  "responseStatus": 200,
  "baseUrl": "https://cma.weegloo.com/v1",
  "requestContentType": "application/json-patch+json",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "roleId": { "type": "string", "description": "The sys.id of the ServiceUserRole", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" },
    "Content-Type": { "type": "string", "description": "application/json-patch+json (RFC 6902 JSON Patch)" },
    "X-Weegloo-Version": { "type": "integer", "description": "The current resource's sys.version (optimistic concurrency control)" }
  },
  "requestBodySchema": {
    "type": "array",
    "description": "An array of RFC 6902 JSON Patch operations (op / path / value / from). path is an RFC 6901 JSON Pointer.",
    "items": {
      "type": "object",
      "required": ["op", "path"],
      "properties": {
        "op": { "type": "string", "enum": ["add", "remove", "replace", "move", "copy", "test"], "description": "Operation kind" },
        "path": { "type": "string", "description": "Target location (JSON Pointer). Example: /description" },
        "value": { "description": "The value used by add/replace/test" },
        "from": { "type": "string", "description": "The source location for move/copy" }
      }
    },
    "example": [
      { "op": "replace", "path": "/description", "value": "Read published products and manage own reviews" }
    ]
  },
  "responseExample": {
    "sys": {
      "id": "3trmXRLXeZN2RTHvVj3hFDN5546vbp",
      "type": "ServiceUserRole",
      "space": { "sys": { "id": "tcq4V2Xb", "type": "Refer", "targetType": "Space" } },
      "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "createdAt": "2026-06-18T12:40:36.944Z",
      "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
      "updatedAt": "2026-06-18T12:41:00.000Z",
      "version": 3
    },
    "name": "Buyer",
    "description": "Read published products and manage own reviews",
    "contentType": { "All": { "Allow": [] } },
    "content": {
      "Read": {
        "Allow": [
          { "contentType": { "sys": { "id": "3trmXRM3RqbgSnifyg7PAmlxvX4fGY", "type": "Refer", "targetType": "ContentType" } } }
        ]
      },
      "Edit": {
        "Allow": [
          { "createdBy": { "sys": { "id": ":self", "type": "Refer", "targetType": "User" } } }
        ]
      }
    },
    "media": { "All": { "Allow": [] } },
    "script": {}
  }
}
```

```api-endpoint
{
  "title": "Delete a ServiceUserRole",
  "method": "DELETE",
  "path": "/spaces/{spaceId}/service-user-roles/{roleId}",
  "description": "Deletes a ServiceUserRole. On success it responds with 204 No Content and no response body.",
  "responseStatus": 204,
  "baseUrl": "https://cma.weegloo.com/v1",
  "pathParameterSchema": {
    "spaceId": { "type": "string", "description": "The sys.id of the Space", "required": true },
    "roleId": { "type": "string", "description": "The sys.id of the ServiceUserRole", "required": true }
  },
  "requestHeaderSchema": {
    "Authorization": { "type": "string", "description": "Bearer token (CMA authentication)" }
  }
}
```

## Related documents {#related-documents}

- [ServiceUser](/api/reference/cma/service-user.md): The signed-up member who receives this role (`roleOverride`).
- [ServiceLogin](/api/reference/cma/service-login.md): Set a *ServiceUserRole* as the default role (`defaultRole`).
- [SpaceRole](/api/reference/cma/space-role.md): The permission bundle for Weegloo Users (same permission-map structure).
