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

# Admin monitoring

> Alert surfaces for team owners and platform admins.

Two read surfaces expose the write-only alert sinks that were previously only visible in tests.

## Team admin alerts

Team owners can list unresolved operational alerts for their team. These carry diagnostic payloads — they are JWT-only and cannot be read by a `mio_sk_` API key.

```text theme={null}
GET /api/v1/teams/{team_id}/admin-alerts
```

**Auth:** team-owner JWT session. API keys are rejected.

**Query parameters:**

| Parameter        | Default | Notes                                                         |
| ---------------- | ------- | ------------------------------------------------------------- |
| `filter[status]` | `open`  | Only `open` is accepted in v1. Any other value returns `422`. |
| `page[size]`     | `50`    | 1–100.                                                        |
| `page[after]`    | —       | Cursor from the previous page's `links.next`.                 |

**Response shape:**

```json theme={null}
{
  "data": [
    {
      "id": "0197...",
      "type": "admin_alerts",
      "attributes": {
        "source_module": "checkout",
        "alert_type": "stripe_sync_drift",
        "hub_id": "hub_abc",
        "payload": { "order_id": "ord_123", "gap_seconds": 420 },
        "created_at": "2026-06-09T14:00:00Z",
        "resolved_at": null,
        "resolved_by": null
      }
    }
  ],
  "meta": { "has_more": false }
}
```

Results are ordered most-recent first. The list returns unresolved alerts only.

***

## Platform admin alerts

Platform admins can list unresolved cross-tenant alerts (abuse signals, infrastructure events).

```text theme={null}
GET /api/v1/admin/platform-alerts
```

**Auth:** `platform_admin` role required.

**Query parameters:**

| Parameter          | Default | Notes                                                                                                  |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------------ |
| `filter[status]`   | `open`  | Only `open` is accepted in v1.                                                                         |
| `filter[severity]` | —       | One of `info`, `warning`, or `critical`. Omit to return all severities. Any other value returns `422`. |
| `page[size]`       | `50`    | 1–100.                                                                                                 |
| `page[after]`      | —       | Pagination cursor.                                                                                     |

**Response shape:**

```json theme={null}
{
  "data": [
    {
      "id": "0197...",
      "type": "platform_alerts",
      "attributes": {
        "alert_type": "rate_limit_surge",
        "severity": "warning",
        "payload": { "ip": "198.51.100.1", "route": "/api/v1/hub/{hub_id}/checkout" },
        "created_at": "2026-06-09T15:00:00Z",
        "resolved_at": null,
        "resolved_by": null
      }
    }
  ],
  "meta": { "has_more": false }
}
```

Results are ordered most-recent first.

***

## Role permissions

Platform admins can assign and remove permissions from roles without rebuilding the role.

```text theme={null}
POST   /api/v1/roles/{role_id}/permissions
DELETE /api/v1/roles/{role_id}/permissions/{permission_slug}
```

**Auth:** JWT session. API keys are rejected.

### Assign a permission

```bash theme={null}
curl -X POST "$MIO_BASE_URL/api/v1/roles/$ROLE_ID/permissions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"slug": "content:read"}'
```

Returns `201` with the updated role resource. Re-assigning a permission the role already holds is a no-op that still returns `201`.

### Remove a permission

```bash theme={null}
curl -X DELETE "$MIO_BASE_URL/api/v1/roles/$ROLE_ID/permissions/content:read" \
  -H "Authorization: Bearer $TOKEN"
```

Returns `204 No Content`. Removing a permission the role does not hold is a no-op that still returns `204`. Returns `404` if the role itself does not exist.
