# net.anisota.graph.scopedMute

> Published by [anisota.net](https://lexicon.garden/identity/did:plc:lcieujcfkv4jx7gehsvok3pr)

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.graph.scopedMute)
- [Documentation](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.graph.scopedMute/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.graph.scopedMute/examples)

## Definitions

### `net.anisota.graph.scopedMute`

**Type**: `record`

An index of the accounts whose reposts or quote posts the viewer has muted through Bluesky's native scoped mute (app.bsky.graph.muteActor with onlyReposts / onlyQuoteposts). Bluesky stores the mute itself, but app.bsky.graph.getMutes returns only fully muted accounts, so a scoped mute is otherwise discoverable only by loading each profile. This record lets Anisota list and undo them, and enforce them client-side on unauthenticated reads where no viewer state comes back. It is a cache, not the source of truth: entries are reconciled against viewerState.mutedOnlyReposts / mutedOnlyQuoteposts and dropped when the server disagrees.

**Key**: `literal:self`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `appView` | `string` | No | The AppView these mutes were last verified against (e.g. 'bluesky', 'blacksky', 'custom'). Native mutes are held per-AppView, so an index written while reading one AppView says nothing about another; without this, verifying the index against a different AppView reads 'that AppView does not hold this mute' as 'the reader lifted this mute' and deletes it. |
| `subjects` | `array` | Yes | The accounts currently carrying a native scoped mute. |
| `createdAt` | `string` (datetime) | Yes | When this index was first written |
| `updatedAt` | `string` (datetime) | No | When this index was last reconciled or edited |

### `net.anisota.graph.scopedMute#scopedMuteEntry`

**Type**: `object`

One account's native scoped mute. At least one scope flag is true — an entry with neither is a full mute or no mute at all, and does not belong here.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `subject` | `string` (did) | Yes | DID of the scope-muted account |
| `createdAt` | `string` (datetime) | No | When this scoped mute was set from Anisota |
| `onlyReposts` | `boolean` | No | Their reposts are muted |
| `onlyQuoteposts` | `boolean` | No | Their quote posts are muted |

## Raw Schema

```json
{
  "id": "net.anisota.graph.scopedMute",
  "defs": {
    "main": {
      "key": "literal:self",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "subjects",
          "createdAt"
        ],
        "properties": {
          "appView": {
            "type": "string",
            "description": "The AppView these mutes were last verified against (e.g. 'bluesky', 'blacksky', 'custom'). Native mutes are held per-AppView, so an index written while reading one AppView says nothing about another; without this, verifying the index against a different AppView reads 'that AppView does not hold this mute' as 'the reader lifted this mute' and deletes it."
          },
          "subjects": {
            "type": "array",
            "items": {
              "ref": "#scopedMuteEntry",
              "type": "ref"
            },
            "maxLength": 1000,
            "description": "The accounts currently carrying a native scoped mute."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this index was first written"
          },
          "updatedAt": {
            "type": "string",
            "format": "datetime",
            "description": "When this index was last reconciled or edited"
          }
        }
      },
      "description": "An index of the accounts whose reposts or quote posts the viewer has muted through Bluesky's native scoped mute (app.bsky.graph.muteActor with onlyReposts / onlyQuoteposts). Bluesky stores the mute itself, but app.bsky.graph.getMutes returns only fully muted accounts, so a scoped mute is otherwise discoverable only by loading each profile. This record lets Anisota list and undo them, and enforce them client-side on unauthenticated reads where no viewer state comes back. It is a cache, not the source of truth: entries are reconciled against viewerState.mutedOnlyReposts / mutedOnlyQuoteposts and dropped when the server disagrees."
    },
    "scopedMuteEntry": {
      "type": "object",
      "required": [
        "subject"
      ],
      "properties": {
        "subject": {
          "type": "string",
          "format": "did",
          "description": "DID of the scope-muted account"
        },
        "createdAt": {
          "type": "string",
          "format": "datetime",
          "description": "When this scoped mute was set from Anisota"
        },
        "onlyReposts": {
          "type": "boolean",
          "default": false,
          "description": "Their reposts are muted"
        },
        "onlyQuoteposts": {
          "type": "boolean",
          "default": false,
          "description": "Their quote posts are muted"
        }
      },
      "description": "One account's native scoped mute. At least one scope flag is true — an entry with neither is a full mute or no mute at all, and does not belong here."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}
```
