---
title: Admin
kind: resource
slug: admin
summary: "Sys-admin surface for per-user platform feature flags. Lists users, flips per-user gates, and bulk-flips gates across a User Group roster."
---

# Admin

Sys-admin surface for per-user platform feature flags. Lists users, flips per-user gates, and bulk-flips gates across a User Group roster.

The **Admin** resource is the API for the `/admin/users` dashboard. Every endpoint is gated on `User.isAdmin = true` — the orthogonal site-admin escape hatch — and writes an `AuditEvents.USER_GATE_TOGGLED` row per *changed* user (no-op flips are silent). Today the only flag exposed is `spaceAgentEnabled` (per-user gate for the Space Agent rollout). As more flags accrete (e.g. `advancedSharing`, `canExternalShare`), the body schema on [Update](#update) widens — the operation count stays at three.

This resource is **not** how directory roles (People Admin / Library Admin) are managed — those are User Group memberships and live under [User Group](/docs/resources/user-group) → members.

## The Admin object

### Attributes

- **`id`** `string` — CUID for the User row. Use this as the `userId` path parameter to [Update](#update).
- **`email`** `string · nullable` — The user's @himarley.com email. Null only in legacy seed data — every Cognito-provisioned account has an email.
- **`name`** `string · nullable` — Display name from Cognito. May be null when the account never set one.
- **`image`** `string · nullable` — Optional avatar URL (typically from Cognito / Entra ID).
- **`isAdmin`** `boolean` — Site-admin flag. Distinct from directory roles below. Site admins have read access to every Droplet + Space + audit log and can flip platform feature gates.
- **`spaceAgentEnabled`** `boolean` — Per-user gate for the Space Agent rollout (feat 038). When false, the user does not see the Agent UI in any Space, even if the Space has an Agent enabled. Toggled per-user (sys-admin only) via [Update](#update) or bulk via [Bulk enable](#bulk-enable).
- **`lastActiveAt`** `timestamp · nullable` — Derived from the most recent `ActivityLog` row for this user. Null when the user has no recorded activity (e.g. provisioned via SSO but never signed in).
- **`systemRoleSlugs`** `string[]` — Slugs of system-role User Groups (e.g. `drop-library-admins`, `drop-people-admins`) the user belongs to. Sorted alphabetically. Empty for users with no system-role memberships.

### JSON example

```json
{
  "id": "usr_alex",
  "email": "alex@himarley.com",
  "name": "Alex Chen",
  "image": null,
  "isAdmin": false,
  "spaceAgentEnabled": true,
  "lastActiveAt": "2026-06-07T11:00:00.000Z",
  "systemRoleSlugs": ["drop-people-admins"]
}
```

## Methods

### List users (sys-admin)

`GET /api/admin/users`

**Sys-admin only.** Paginated directory of all users with per-user platform feature flag state (`spaceAgentEnabled`), role chips (Sys Admin / People Admin / Library Admin), and a last-active timestamp derived from the most recent `ActivityLog` row. Supports case-insensitive substring search across name + email via `q`. Default page size 50, max 200. Mirrors the `/admin/users` SSR page so CLI + MCP consumers can audit per-user gate state.

**Parameters**

- **`page`** _(number · query)_ — 1-indexed page number; defaults to 1.
- **`limit`** _(number · query)_ — Rows per page; default 50, max 200.
- **`q`** _(string · query)_ — Substring search over name + email.

**CLI**

```bash
drop admin users list --page 1 --q alex
```

**MCP**

```json
{
  "tool": "drop_admin_users_list",
  "arguments": {
    "page": 1,
    "q": "alex"
  }
}
```

**HTTP**

```bash
curl -X GET 'https://drop.himarley.ai/api/admin/users' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
{
  "users": [
    {
      "id": "usr_alex",
      "email": "alex@himarley.com",
      "name": "Alex Chen",
      "image": null,
      "isAdmin": false,
      "spaceAgentEnabled": true,
      "lastActiveAt": "2026-06-07T11:00:00.000Z",
      "systemRoleSlugs": [
        "people-admin"
      ]
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "totalPages": 1
  }
}
```

### Update a user (sys-admin)

`PATCH /api/admin/users/{userId}`

**Sys-admin only.** Flip per-user platform feature flags. Today the only flag is `spaceAgentEnabled`; as more accrete (e.g. `advancedSharing`, `libraryAdmin`) the body schema widens but the operation stays at one PATCH. No-op flips (passing the value the user already has) succeed with the current state and write no audit row. Every successful state change writes an `AuditEvents.USER_GATE_TOGGLED` row. **NOT** the place for role grants — Library / People Admin live on UserGroup membership, not on User columns.

**Parameters**

- **`userId`** _(string · path · required)_ — Target user id.
- **`spaceAgentEnabled`** _(boolean · body)_ — New per-user Space Agent gate value.

**CLI**

```bash
drop admin users update usr_alex --space-agent-enabled
```

**MCP**

```json
{
  "tool": "drop_admin_user_update",
  "arguments": {
    "userId": "usr_alex",
    "spaceAgentEnabled": true
  }
}
```

**HTTP**

```bash
curl -X PATCH 'https://drop.himarley.ai/api/admin/users/usr_alex' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"spaceAgentEnabled":true}'
```

**Response** (200)

```json
{
  "user": {
    "id": "usr_alex",
    "spaceAgentEnabled": true
  }
}
```

### Bulk-flip a feature gate by User Group (sys-admin)

`POST /api/admin/users/bulk-enable`

**Sys-admin only.** Flip `User.spaceAgentEnabled` for every member of a User Group in a single batched UPDATE. Members already at the target value are skipped — no audit-log noise, only changed users produce `AuditEvents.USER_GATE_TOGGLED` rows. Returns `totalMembers` (roster size) and `changedCount` (rows actually flipped). System role groups (Library / People Admin) are valid targets — bulk-enabling Space Agent for every Library Admin is a sensible rollout move.

**Parameters**

- **`userGroupId`** _(string · body · required)_ — UserGroup id whose members to flip.
- **`spaceAgentEnabled`** _(boolean · body · required)_ — Target value for every member.

**CLI**

```bash
drop admin users bulk-enable --user-group-id grp_engineering --space-agent-enabled
```

**MCP**

```json
{
  "tool": "drop_admin_user_bulk_enable",
  "arguments": {
    "userGroupId": "grp_engineering",
    "spaceAgentEnabled": true
  }
}
```

**HTTP**

```bash
curl -X POST 'https://drop.himarley.ai/api/admin/users/bulk-enable' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"userGroupId":"grp_engineering","spaceAgentEnabled":true}'
```

**Response** (200)

```json
{
  "groupId": "grp_engineering",
  "groupSlug": "engineering",
  "totalMembers": 24,
  "changedCount": 18
}
```
