Skip to content

User Management

Admin-only endpoints for listing users and managing their roles and notebook permissions. User data is sourced from the Clerk Backend API.

Base path: /api/admin

Clerk Dependency

These endpoints require a valid CLERK_SECRET_KEY in the server configuration. In bypass auth mode, they return mock data for the dev-user.


GET /api/admin/users

List all users from Clerk with their roles and notebook permissions.

Auth: Admin

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "users": [
      {
        "user_id": "user_abc123",
        "email": "admin@example.com",
        "first_name": "Admin",
        "last_name": "User",
        "role": "admin",
        "notebook_permissions": {},
        "created_at": "2026-01-15T10:00:00Z",
        "last_sign_in_at": "2026-02-25T08:30:00Z"
      },
      {
        "user_id": "user_def456",
        "email": "viewer@example.com",
        "first_name": "Regular",
        "last_name": "User",
        "role": "user",
        "notebook_permissions": {
          "a1b2c3d4": "chat_only"
        }
      }
    ]
  }
}
Code Cause
401 Invalid or missing token
403 Non-admin user
502 Clerk API unreachable or returned an error
curl http://localhost:8000/api/admin/users \
  -H "Authorization: Bearer $TOKEN"
import httpx

response = httpx.get(
    "http://localhost:8000/api/admin/users",
    headers={"Authorization": f"Bearer {token}"},
)
users = response.json()["data"]["users"]
for u in users:
    print(f"  {u['email']} (role: {u['role']})")

GET /api/admin/users/{user_id}

Get a single user's details from Clerk.

Auth: Admin

Headers:

Header Value
Authorization Bearer <token>

Status: 200 OK

{
  "success": true,
  "data": {
    "user_id": "user_abc123",
    "email": "admin@example.com",
    "first_name": "Admin",
    "last_name": "User",
    "role": "admin",
    "notebook_permissions": {},
    "created_at": "2026-01-15T10:00:00Z",
    "last_sign_in_at": "2026-02-25T08:30:00Z"
  }
}
Code Cause
401 Invalid or missing token
403 Non-admin user
404 User not found in Clerk
502 Clerk API unreachable
curl http://localhost:8000/api/admin/users/user_abc123 \
  -H "Authorization: Bearer $TOKEN"
import httpx

user_id = "user_abc123"
response = httpx.get(
    f"http://localhost:8000/api/admin/users/{user_id}",
    headers={"Authorization": f"Bearer {token}"},
)
user = response.json()["data"]
print(f"{user['email']}: {user['role']}")

PUT /api/admin/users/{user_id}/permissions

Update a user's notebook permissions and optionally their role. Writes to Clerk's public_metadata so permissions are available on the frontend via the Clerk session.

Auth: Admin

Headers:

Header Value
Authorization Bearer <token>
Content-Type application/json

Body:

{
  "notebook_permissions": {
    "a1b2c3d4-e5f6-7890-abcd-ef1234567890": "chat_only",
    "f9e8d7c6-b5a4-3210-fedc-ba9876543210": "full_access"
  },
  "role": "user"
}
Field Type Required Default Description
notebook_permissions object Yes -- Map of notebook_id to permission level
role string No -- User role ("admin" or "user")

Permission levels:

Level Description
"chat_only" Can only use chat in the notebook
"full_access" Full read/write access to the notebook

Status: 200 OK

{
  "success": true,
  "data": {
    "success": true
  }
}
Code Cause
401 Invalid or missing token
403 Non-admin user
404 User not found in Clerk
502 Clerk API unreachable
curl -X PUT http://localhost:8000/api/admin/users/user_def456/permissions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "notebook_permissions": {"a1b2c3d4": "chat_only"},
    "role": "user"
  }'
import httpx

user_id = "user_def456"
response = httpx.put(
    f"http://localhost:8000/api/admin/users/{user_id}/permissions",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "notebook_permissions": {"a1b2c3d4": "chat_only"},
        "role": "user",
    },
)
print(response.json()["data"])