> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memorylake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Role Access Scope

> Replaces the scope of each listed resource type for everyone holding the role

```
PUT /openapi/memorylake/admin/v1/roles/{role_key}/access-scope
```

Replaces the scope of each listed resource type for everyone holding the role. A scope limits; it never grants more than the role allows. Applies to tenant\_admin, tenant\_member and custom roles — the owner role cannot be limited (409). Project instances need their workspace\_id.

The response carries an `ETag` header (the same value a GET of this resource returns). Send it back in `If-Match` to make the write conditional: when the resource has changed in the meantime the write is refused with 412 and nothing is changed. The check narrows, but does not fully close, the window for a concurrent overwrite — two writers that pass it at the same instant can both write.

<Note>
  **Permission required:** `policy:manage`

  * Changes that give someone an admin role, or that reduce what an admin can reach, also require the team owner or an admin.
</Note>

### Path Parameters

<ParamField path="role_key" type="string" required>
  tenant\_admin, tenant\_member or a custom role key
</ParamField>

### Headers

<ParamField header="If-Match" type="string">
  Optional. The ETag from a previous read of this resource. The write is refused with 412 when the resource has changed since; omit it to overwrite unconditionally.
</ParamField>

### Request Body

<ParamField body="reason" type="string" required>
  Why the change is made; recorded in the audit log. At most 255 bytes (UTF-8).
</ParamField>

<ParamField body="scopes" type="array" required>
  Each listed resource type's scope is replaced by the given one; types not listed keep their current scope.

  <Expandable title="Access Scope Entry object">
    <ParamField body="scopes[].mode" type="string" required>all = every instance; instances = only the listed ones</ParamField>
    <ParamField body="scopes[].resource_type" type="string" required>Resource type, e.g. memorylake:project</ParamField>

    <ParamField body="scopes[].instances" type="array">
      Required when mode is instances

      <Expandable title="Access Scope Instance object">
        <ParamField body="scopes[].instances[].id" type="string" required>Instance id</ParamField>
        <ParamField body="scopes[].instances[].actions" type="array">Omit for every action the member's role allows</ParamField>
        <ParamField body="scopes[].instances[].via_permission_level" type="boolean">Echo of a read-only row. Instances marked true are skipped on write — permission levels are set on the resource, not through scope.</ParamField>
        <ParamField body="scopes[].instances[].workspace_id" type="string">Parent workspace — required for project instances</ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X PUT 'https://app.memorylake.ai/openapi/memorylake/admin/v1/roles/data_analyst/access-scope' \
    -H 'Authorization: Bearer sk_xxxxxx' \
    -H 'Content-Type: application/json' \
    -d '{
      "reason": "example",
      "scopes": [
        {
          "mode": "all",
          "resource_type": "example",
          "instances": [
            {
              "id": "185afe41ca6ac4566fdc7a9adeabf5a0",
              "actions": [],
              "via_permission_level": false,
              "workspace_id": "12404b77739317d2b08fc918a95f0be9"
            }
          ]
        }
      ]
    }'
  ```
</RequestExample>

### Response

<ResponseField name="data" type="object">
  <Expandable title="Role Access Scope object">
    <ResponseField name="role_key" type="string">The role</ResponseField>

    <ResponseField name="scopes" type="array">
      One entry per scopable resource type

      <Expandable title="Access Scope Entry object">
        <ResponseField name="mode" type="string">all = every instance; instances = only the listed ones</ResponseField>
        <ResponseField name="resource_type" type="string">Resource type, e.g. memorylake:project (see GET /permission-catalog)</ResponseField>
        <ResponseField name="available_actions" type="array">Read-only. Instance-level actions the member's role grants for this type — the most a scope entry can allow.</ResponseField>

        <ResponseField name="instances" type="array">
          The instances, when mode is instances

          <Expandable title="Access Scope Instance object">
            <ResponseField name="id" type="string">Instance id, as returned by the data API</ResponseField>
            <ResponseField name="actions" type="array">Actions allowed on this instance. Omit for every action the member's role allows.</ResponseField>
            <ResponseField name="effective_actions" type="array">Read-only. The subset of actions the member's CURRENT role still grants.</ResponseField>
            <ResponseField name="permission_level" type="string">Read-only. The permission level, when via\_permission\_level is true. One of: `read`, `write`, `manage`.</ResponseField>
            <ResponseField name="shadowed_actions" type="array">Read-only. Actions stored here that the member's current role no longer grants.</ResponseField>
            <ResponseField name="via_permission_level" type="boolean">Read-only. The member reaches this instance through a permission level granted on it, not through this scope. May be echoed back on write; such instances are skipped.</ResponseField>
            <ResponseField name="workspace_id" type="string">Parent workspace of a project instance. Required when writing a project instance.</ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Success (200) theme={null}
  {
    "success": true,
    "message": "Operation completed successfully",
    "data": {
      "role_key": "tenant_member",
      "scopes": [
        {
          "mode": "all",
          "resource_type": "example",
          "available_actions": [
            "example"
          ],
          "instances": [
            {
              "id": "bc572b050c9920425b5fd75681eccbb2",
              "actions": [],
              "effective_actions": [],
              "permission_level": "read",
              "shadowed_actions": [],
              "via_permission_level": false,
              "workspace_id": "0fa2d21dc175adc7a003e0b37f156cb1"
            }
          ]
        }
      ]
    }
  }
  ```
</ResponseExample>

### Errors

Errors answer with `success: false`, a `message` and an `error_code`. See [Error Codes](/features/memorylake/api-reference/errors) for every code.

| Status | Meaning |
| - | - |
| `400` | A parameter or the body is invalid |
| `401` | The API key is missing, invalid, disabled or expired |
| `403` | The key is not allowed to do this |
| `404` | The resource does not exist |
| `409` | The request conflicts with the current state, e.g. a duplicate or a limit reached |
| `412` | The `If-Match` value no longer matches: the resource changed since you read it |
| `422` | The body or a parameter failed validation |
| `429` | Too many requests. Wait for the time in `Retry-After` |
| `500` | Server-side error |
| `503` | Temporarily unavailable. Retry later |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.