---
title: "Dashboard Views"
description: "The administrative dashboard provides a centralized Next.js interface for managing self-hosted instances, monitoring runtime memory operations, inspecting stored entities, and configuring system-le..."
last_updated: "2026-10-11T17:37:10.257685+00:00"
canonical_url: "https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/server-dashboard/dashboard-views"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [server/dashboard/src/app/root/dashboard/memories/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx)
- [server/dashboard/src/app/setup/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/setup/page.tsx)
- [server/dashboard/src/app/root/dashboard/api-keys/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx)
- [server/dashboard/src/app/root/dashboard/entities/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx)
- [server/dashboard/src/app/root/dashboard/configuration/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx)
- [server/dashboard/src/app/root/dashboard/requests/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx)
- [integrations/opencode-plugin/opencode-mem0.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts)
- [server/dashboard/src/app/root/dashboard/components/main-nav.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/main-nav.tsx)
- [mem0-ts/src/oss/src/memory/index.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/memory/index.ts)
- [server/dashboard/src/app/root/dashboard/settings/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/settings/page.tsx)
- [server/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/main.py)
- [integrations/n8n-nodes-mem0/nodes/Mem0/Mem0.node.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/n8n-nodes-mem0/nodes/Mem0/Mem0.node.ts)
- [server/dashboard/src/app/root/dashboard/analytics/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/analytics/page.tsx)
- [server/routers/entities.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/routers/entities.py)
- [integrations/antigravity-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/memory_core.py)
- [mem0/memory/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/memory/main.py)
- [integrations/agent-plugin-core/python/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/agent-plugin-core/python/memory_core.py)
- [server/dashboard/src/app/root/dashboard/components/nav-wrapper.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/nav-wrapper.tsx)
- [cli/node/src/commands/memory.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/cli/node/src/commands/memory.ts)
- [server/dashboard/src/app/root/dashboard/webhooks/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/webhooks/page.tsx)
- [cli/node/src/commands/entities.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/cli/node/src/commands/entities.ts)
- [server/dashboard/src/utils/api-endpoints.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts)
- [server/dashboard/src/app/root/dashboard/export/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/export/page.tsx)
- [server/dashboard/src/types/api.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/types/api.ts)
- [mem0/client/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/client/main.py)
- [cli/node/src/backend/platform.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/cli/node/src/backend/platform.ts)
- [server/dashboard/src/components/ui/dialog.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/dialog.tsx)
- [server/dashboard/src/components/ui/use-toast.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/use-toast.ts)
- [server/dashboard/src/hooks/use-api-query.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/hooks/use-api-query.ts)
- [server/dashboard/src/lib/error-message.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/lib/error-message.ts)
</details>

## Overview

The administrative dashboard provides a centralized Next.js interface for managing self-hosted instances, monitoring runtime memory operations, inspecting stored entities, and configuring system-level parameters through authenticated API query hooks and state management providers. Sources: [server/dashboard/src/app/setup/page.tsx](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/setup/page.tsx#L45-L64), [server/dashboard/src/hooks/use-api-query.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/hooks/use-api-query.ts#L18-L56)

## Navigation and Shell Layout

### Sidebar and Shell Structure

The dashboard layout combines a fixed sidebar shell container managed by Redux layout state with collapsible navigation groups, instance branding, and a top-bar control header. The primary navigation shell uses `NavWrapper` to compute responsive positioning based on whether `isSidebarCollapsed` is active, utilizing layout widths defined by `SIDEBAR_WIDTH` and `COLLAPSED_SIDEBAR_WIDTH`. A toggle button rendered in the top header triggers the `toggleSidebar` Redux action, altering both the fixed container width and the adjacent main content offset.

Sources: [server/dashboard/src/app/root/dashboard/components/nav-wrapper.tsx:31-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/nav-wrapper.tsx#L31-L51)

> [!NOTE]
> When the sidebar is collapsed, collapsible triggers and textual labels (such as group titles and user email identifiers) are hidden, while tooltips are automatically passed to `SidebarMenuButton` components to display the item titles on hover.

Sources: [server/dashboard/src/app/root/dashboard/components/main-nav.tsx:44-64](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/main-nav.tsx#L44-L64)

### Navigation Item Routing and Categories

The `MainNav` component organizes dashboard links into three distinct functional sections: **ACTIVITY**, **CLOUD FEATURES**, and **ACCOUNT**. Each section groups route definitions that map to Lucide icons and match the current router path via `usePathname`.

| Section | Title | URL | Icon |
| :--- | :--- | :--- | :--- |
| **ACTIVITY** | Requests | `/dashboard/requests` | `Activity` |
| **ACTIVITY** | Memories | `/dashboard/memories` | `GalleryVerticalEnd` |
| **ACTIVITY** | Entities | `/dashboard/entities` | `Users` |
| **CLOUD FEATURES** | Categories | `/dashboard/categories` | `Tags` |
| **CLOUD FEATURES** | Webhooks | `/dashboard/webhooks` | `WebhookIcon` |
| **CLOUD FEATURES** | Analytics | `/dashboard/analytics` | `ChartLine` |
| **CLOUD FEATURES** | Export | `/dashboard/export` | `FolderInput` |
| **ACCOUNT** | API Keys | `/dashboard/api-keys` | `KeyRound` |
| **ACCOUNT** | Configuration | `/dashboard/configuration` | `Wrench` |
| **ACCOUNT** | Settings | `/dashboard/settings` | `Settings` |

```tsx
{[
  {
    title: "Requests",
    url: "/dashboard/requests",
    icon: Activity,
    active: pathname === "/dashboard/requests",
  },
  {
    title: "Memories",
    url: "/dashboard/memories",
    icon: GalleryVerticalEnd,
    active: pathname === "/dashboard/memories",
  },
  {
    title: "Entities",
    url: "/dashboard/entities",
    icon: Users,
    active: pathname === "/dashboard/entities",
  },
```
Sources: [server/dashboard/src/app/root/dashboard/components/main-nav.tsx:65-83](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/main-nav.tsx#L65-L83), [server/dashboard/src/app/root/dashboard/components/main-nav.tsx:132-152](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/main-nav.tsx#L132-L152), [server/dashboard/src/app/root/dashboard/components/main-nav.tsx:199-217](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/main-nav.tsx#L199-L217)

### User Profile and Dropdown Menu

At the base of the expanded sidebar shell, `NavWrapper` renders a user profile widget connected to `useAuth`. Clicking the user trigger opens a `DropdownMenu` providing direct navigation to user settings and a `logout` handler.

```tsx
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <button className="flex items-center gap-2 w-full text-left hover:bg-surface-default-secondary-hover rounded-md p-1.5 transition-colors">
      <div className="grid size-7 place-items-center rounded-md bg-surface-default-tertiary text-onSurface-default-secondary text-xs font-semibold shrink-0">
        {user?.name?.charAt(0).toUpperCase() || "?"}
      </div>
      <div className="flex flex-col min-w-0">
        <span className="typo-body-xs text-onSurface-default-primary truncate">
          {user?.name}
        </span>
        <span className="typo-caption-sm text-onSurface-default-tertiary truncate">
          {user?.email}
        </span>
      </div>
    </button>
  </DropdownMenuTrigger>
  <DropdownMenuContent
    align="start"
    side="top"
    className="w-56 font-fustat bg-surface-default-primary border-memBorder-secondary"
  >
    <div className="px-2 py-1.5">
      <p className="typo-body-sm text-onSurface-default-primary">
        {user?.name}
      </p>
      <p className="typo-body-xs text-onSurface-default-tertiary">
        {user?.email}
      </p>
    </div>
    <DropdownMenuSeparator className="bg-memBorder-primary" />
    <DropdownMenuItem
      asChild
      className="typo-body-sm text-onSurface-default-primary hover:bg-surface-default-tertiary-hover focus:bg-surface-default-tertiary-hover cursor-pointer"
    >
      <Link href="/dashboard/settings">
        <Settings className="size-4 mr-2" />
        Settings
      </Link>
    </DropdownMenuItem>
    <DropdownMenuSeparator className="bg-memBorder-primary" />
    <DropdownMenuItem
      onClick={logout}
      className="typo-body-sm text-onSurface-default-primary hover:bg-surface-default-tertiary-hover focus:bg-surface-default-tertiary-hover cursor-pointer"
    >
      <LogOut className="size-4 mr-2" />
      Log out
    </DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>
```
Sources: [server/dashboard/src/app/root/dashboard/components/nav-wrapper.tsx:82-130](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/components/nav-wrapper.tsx#L82-L130)

## Memories Inspection and Deletion

### Data Table Rendering and Pagination

The `MemoriesPage` component retrieves records from the backend API using `useApiQuery`, querying `MEMORY_ENDPOINTS.BASE` with an optional `user_id` query parameter and a maximum fetch limit (`MEMORY_FETCH_LIMIT`) set to `1000`. The raw response extracts results via `res.data?.results ?? res.data ?? []`. When total records reach or exceed `MEMORY_FETCH_LIMIT`, an `UpgradeBanner` renders with a cloud upgrade CTA. Client-side pagination slices the fetched list using a fixed `PAGE_SIZE` of `20` records per page.

```tsx
const PAGE_SIZE = 20;
// Keep in sync with ALL_MEMORIES_LIMIT in server/main.py.
const MEMORY_FETCH_LIMIT = 1000;

export default function MemoriesPage() {
  const [userId, setUserId] = useState("");
  const [selectedMemory, setSelectedMemory] = useState<Memory | null>(null);
  const [memoryToDelete, setMemoryToDelete] = useState<Memory | null>(null);
  const [page, setPage] = useState(0);
  const apiUrl = process.env.NEXT_PUBLIC_API_URL || "";

  const {
    data: memories = [],
    isLoading,
    refetch,
  } = useApiQuery<Memory[]>(
    async () => {
      const params = userId.trim()
        ? { user_id: userId.trim(), top_k: MEMORY_FETCH_LIMIT }
        : { top_k: MEMORY_FETCH_LIMIT };
      const res = await api.get(MEMORY_ENDPOINTS.BASE, { params });
      const raw = res.data?.results ?? res.data ?? [];
      return Array.isArray(raw) ? raw : [];
    },
    { errorToast: "Failed to load memories", initialData: [] },
  );

  const totalPages = Math.ceil(memories.length / PAGE_SIZE);
  const paginatedMemories = memories.slice(
    page * PAGE_SIZE,
    (page + 1) * PAGE_SIZE,
  );
```
Sources: [server/dashboard/src/app/root/dashboard/memories/page.tsx:29-60](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L29-L60)

The table columns display specific memory attributes mapped from the `Memory` interface:

| Column Label | Key | Width | Render Behavior |
| :--- | :--- | :--- | :--- |
| **Content** | `memory` | `400` | Clamped to 2 lines (`line-clamp-2 text-sm`) |
| **User** | `user_id` | `100` | Raw string rendering |
| **Agent** | `agent_id` | `100` | Raw string rendering |
| **Created** | `created_at` | `120` | Formatted via date-fns (`MMM d, yyyy`) or `--` |

```tsx
const columns = [
  {
    key: "memory" as keyof Memory,
    label: "Content",
    width: 400,
    render: (value: string) => (
      <span className="line-clamp-2 text-sm">{value}</span>
    ),
  },
  { key: "user_id" as keyof Memory, label: "User", width: 100 },
  { key: "agent_id" as keyof Memory, label: "Agent", width: 100 },
  {
    key: "created_at" as keyof Memory,
    label: "Created",
    width: 120,
    render: (value: string) =>
      value ? format(new Date(value), "MMM d, yyyy") : "--",
  },
];
```
Sources: [server/dashboard/src/app/root/dashboard/memories/page.tsx:79-97](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L79-L97)

> [!NOTE]
> Pressing the Enter key while typing inside the User ID filter input resets the pagination index to `0` and triggers an immediate query refetch.

```tsx
  <Input
    placeholder="Filter by User ID (optional)"
    value={userId}
    onChange={(e) => setUserId(e.target.value)}
    onKeyDown={(e) => {
      if (e.key === "Enter") {
        setPage(0);
        refetch();
      }
    }}
    className="w-64"
  />
</div>
```
Sources: [server/dashboard/src/app/root/dashboard/memories/page.tsx:114-126](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L114-L126)

### Inspection Sheet and Deletion Flow

Clicking any row in the `DataTable` assigns the selected `Memory` object to local state via `onRowClick`, activating the inspection `Sheet` component. The sheet displays metadata and details for the selected memory item while highlighting the active row with a background utility class (`bg-surface-default-tertiary`).

```tsx
<Card className="border-memBorder-primary overflow-hidden">
  <DataTable
    data={paginatedMemories}
    columns={columns}
    getRowKey={(row) => row.id}
    onRowClick={(row) => setSelectedMemory(row)}
    getRowClassName={(row) =>
      selectedMemory?.id === row.id
        ? "bg-surface-default-tertiary"
        : undefined
    }
  />
</Card>
```
Sources: [server/dashboard/src/app/root/dashboard/memories/page.tsx:152-164](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L152-L164), [server/dashboard/src/app/root/dashboard/memories/page.tsx:195-208](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L195-L208)

Deletion actions execute against `MEMORY_ENDPOINTS.BY_ID(memoryToDelete.id)` using `api.delete`. Success responses trigger a toast notification with a `"success"` variant, clear the inspection sheet if the deleted memory was currently open, reset `memoryToDelete`, and invoke `refetch()`. Errors are intercepted by `getErrorMessage` and displayed via a destructive toast.

```tsx
const handleDelete = async () => {
  if (!memoryToDelete) return;
  try {
    await api.delete(MEMORY_ENDPOINTS.BY_ID(memoryToDelete.id));
    toast({ title: "Memory deleted", variant: "success" });
    if (selectedMemory?.id === memoryToDelete.id) setSelectedMemory(null);
    setMemoryToDelete(null);
    void refetch();
  } catch (error) {
    toast({
      title: "Failed to delete memory",
      description: getErrorMessage(error),
      variant: "destructive",
    });
  }
};
```
Sources: [server/dashboard/src/app/root/dashboard/memories/page.tsx:62-77](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/memories/page.tsx#L62-L77)

## Entity Exploration and Graph Cleanup

### Entities List Presentation and Metadata

The `EntitiesPage` component queries `ENTITY_ENDPOINTS.BASE` via `useApiQuery` to fetch a collection of `Entity` records. While loading, it renders a `TableSkeleton` component with 5 rows and 5 columns. If the resulting entity array is empty, it displays an `EmptyState` component indicating that entities appear once memories are stored with a `user_id`, `agent_id`, or `run_id`. Otherwise, it wraps a `DataTable` component inside a styled `Card` element.

```tsx
export default function EntitiesPage() {
  const [entityToDelete, setEntityToDelete] = useState<Entity | null>(null);

  const {
    data: entities = [],
    isLoading,
    refetch,
  } = useApiQuery<Entity[]>(
    async () => {
      const res = await api.get<Entity[]>(ENTITY_ENDPOINTS.BASE);
      return res.data ?? [];
    },
    { errorToast: "Failed to load entities", initialData: [] },
  );
```
Sources: [server/dashboard/src/app/root/dashboard/entities/page.tsx:20-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L20-L33), [server/dashboard/src/app/root/dashboard/entities/page.tsx:102-121](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L102-L121)

The table structures entity records using the following column schema:

| Column Label | Key | Width | Render Behavior |
| :--- | :--- | :--- | :--- |
| **Type** | `type` | `100` | Rendered as a capitalized outline `Badge` |
| **ID** | `id` | `280` | Monospace truncated text (`font-mono text-sm truncate`) |
| **Memories** | `total_memories` | `100` | Right-aligned numeric counter |
| **Last Active** | `updated_at` | `140` | Formatted via date-fns (`MMM d, yyyy`) or `--` |
| **Actions** | `id` | `40` | Ghost icon button rendering a `Trash2` trigger |

```tsx
const columns = [
  {
    key: "type" as keyof Entity,
    label: "Type",
    width: 100,
    render: (value: Entity["type"]) => (
      <Badge variant="outline" className="capitalize">
        {value}
      </Badge>
    ),
  },
  {
    key: "id" as keyof Entity,
    label: "ID",
    width: 280,
    render: (value: string) => (
      <span className="font-mono text-sm truncate">{value}</span>
    ),
  },
  {
    key: "total_memories" as keyof Entity,
    label: "Memories",
    width: 100,
    align: "right" as const,
  },
  {
    key: "updated_at" as keyof Entity,
    label: "Last Active",
    width: 140,
    render: (value: string | null) =>
      value ? format(new Date(value), "MMM d, yyyy") : "--",
  },
  {
    key: "id" as keyof Entity,
    label: "",
    width: 40,
    render: (_: string, row: Entity) => (
      <Button
        variant="ghost"
        size="icon"
        onClick={() => setEntityToDelete(row)}
        className="size-7"
      >
        <Trash2 className="size-3.5 text-onSurface-danger-primary" />
      </Button>
    ),
  },
];
```
Sources: [server/dashboard/src/app/root/dashboard/entities/page.tsx:53-100](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L53-L100)

> [!NOTE]
> The `EntityType` definition strictly restricts entity classification values to three types: `"user"`, `"agent"`, and `"run"`.

```typescript
export type EntityType = "user" | "agent" | "run";
```
Sources: [server/dashboard/src/types/api.ts:36-36](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/types/api.ts#L36-L36)

### Entity Deletion and Cleanup Flow

Clicking the trash icon button on any entity row sets that specific `Entity` object into the `entityToDelete` local state variable. This action opens the `DeleteConfirmationModal` component, which displays a warning description stating that all memories associated with the entity will be permanently removed.

```tsx
  key: "id" as keyof Entity,
  label: "",
  width: 40,
  render: (_: string, row: Entity) => (
    <Button
      variant="ghost"
      size="icon"
      onClick={() => setEntityToDelete(row)}
      className="size-7"
    >
      <Trash2 className="size-3.5 text-onSurface-danger-primary" />
    </Button>
  ),
},
```
Sources: [server/dashboard/src/app/root/dashboard/entities/page.tsx:86-99](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L86-L99), [server/dashboard/src/app/root/dashboard/entities/page.tsx:123-131](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L123-L131)

Confirming deletion triggers the `handleDelete` function, which issues an HTTP DELETE request to `ENTITY_ENDPOINTS.BY_ID(entityToDelete.type, entityToDelete.id)`. The endpoint dynamically formats the URL path using `encodeURIComponent(id)` to handle identifiers safely. On success, a toast notification displays `"Entity deleted"` with a `"success"` variant, the deletion modal state is cleared, and `refetch` is invoked to update the table data.

```tsx
const handleDelete = async () => {
  if (!entityToDelete) return;
  try {
    await api.delete(
      ENTITY_ENDPOINTS.BY_ID(entityToDelete.type, entityToDelete.id),
    );
    toast({ title: "Entity deleted", variant: "success" });
    setEntityToDelete(null);
    void refetch();
  } catch (error) {
    toast({
      title: "Failed to delete entity",
      description: getErrorMessage(error),
      variant: "destructive",
    });
  }
};
```
Sources: [server/dashboard/src/app/root/dashboard/entities/page.tsx:35-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L35-L51), [server/dashboard/src/utils/api-endpoints.ts:30-34](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts#L30-L34)

> [!WARNING]
> If the deletion request fails, `getErrorMessage(error)` extracts the server error detail or fallback message, displaying it inside a destructive toast notification.

```tsx
} catch (error) {
  toast({
    title: "Failed to delete entity",
    description: getErrorMessage(error),
    variant: "destructive",
  });
}
```
Sources: [server/dashboard/src/app/root/dashboard/entities/page.tsx:44-50](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/entities/page.tsx#L44-L50), [server/dashboard/src/lib/error-message.ts:3-19](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/lib/error-message.ts#L3-L19)

## API Key Management and Dialogs

### Table Listing and Column Configuration

The `ApiKeysPage` component renders a data table displaying existing API keys retrieved from the backend. The underlying data query utilizes `useApiQuery` targeting `API_KEY_ENDPOINTS.BASE`, falling back to an empty array if no keys are returned. When three or more keys exist, an `UpgradeBanner` element is displayed above the table layout.

```tsx
const {
  data: keys = [],
  isLoading,
  refetch,
} = useApiQuery<ApiKey[]>(
  async () => {
    const res = await api.get<ApiKey[]>(API_KEY_ENDPOINTS.BASE);
    return res.data ?? [];
  },
  { errorToast: "Failed to load API keys", initialData: [] },
);
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:37-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L37-L47), [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:206-210](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L206-L210)

The table structures key records using the following column schema:

| Column Label | Key | Width | Render Behavior |
| :--- | :--- | :--- | :--- |
| **Label** | `label` | `150` | Plain text label |
| **Key** | `key_prefix` | `120` | Monospace code snippet rendering prefix with ellipsis (`...`) |
| **Created** | `created_at` | `120` | Formatted via date-fns (`MMM d, yyyy`) |
| **Last Used** | `last_used_at` | `120` | Formatted via date-fns or rendered as `"Never"` |
| **Actions** | `id` | `40` | Ghost icon button rendering a `Trash2` trigger to assign `keyToRevoke` |

```tsx
const columns = [
  { key: "label" as keyof ApiKey, label: "Label", width: 150 },
  {
    key: "key_prefix" as keyof ApiKey,
    label: "Key",
    width: 120,
    render: (value: string) => (
      <code className="text-xs font-mono">{value}...</code>
    ),
  },
  {
    key: "created_at" as keyof ApiKey,
    label: "Created",
    width: 120,
    render: (value: string) => format(new Date(value), "MMM d, yyyy"),
  },
  {
    key: "last_used_at" as keyof ApiKey,
    label: "Last Used",
    width: 120,
    render: (value: string | null) =>
      value ? format(new Date(value), "MMM d, yyyy") : "Never",
  },
  {
    key: "id" as keyof ApiKey,
    label: "",
    width: 40,
    render: (_: string, row: ApiKey) => (
      <Button
        variant="ghost"
        size="icon"
        onClick={() => setKeyToRevoke(row)}
        className="size-7"
      >
        <Trash2 className="size-3.5 text-onSurface-danger-primary" />
      </Button>
    ),
  },
];
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:90-128](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L90-L128)

> [!NOTE]
> The `ApiKey` TypeScript interface defines properties for `id`, `label`, `key_prefix`, `created_at`, and an optional `last_used_at` timestamp.

```typescript
export interface ApiKey {
  id: string;
  label: string;
  key_prefix: string;
  created_at: string;
  last_used_at: string | null;
}
```
Sources: [server/dashboard/src/types/api.ts:10-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/types/api.ts#L10-L16)

### Creation Dialog Modals and Clipboard Copying

Clicking the "Create Key" button opens a Radix-backed `Dialog` component controlled by `createOpen` state. The dialog content transitions between two distinct states based on whether `newKey` has been populated by a successful creation response.

```tsx
return (
  <div className="space-y-4">
    <div className="flex items-center justify-between">
      <h1 className="text-xl font-semibold font-fustat">API Keys</h1>
      <Dialog open={createOpen} onOpenChange={handleDialogClose}>
        <DialogTrigger asChild>
          <Button size="sm">
            <Plus className="size-4 mr-1" /> Create Key
          </Button>
        </DialogTrigger>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create API Key</DialogTitle>
          </DialogHeader>
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:130-143](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L130-L143)

When `newKey` is empty, the modal presents a form input for the `newLabel` string and a disabled-until-typed "Create" action button. Executing `handleCreate` posts to `API_KEY_ENDPOINTS.BASE`, assigns the returned plain-text secret to `newKey`, and triggers a table `refetch`. Once generated, the view swaps to display the raw key inside a read-only input paired with a `CopyToClipboard` component that temporarily toggles check icon feedback.

```tsx
const handleCreate = async () => {
  try {
    const res = await api.post<ApiKeyCreateResponse>(API_KEY_ENDPOINTS.BASE, {
      label: newLabel,
    });
    setNewKey(res.data.key);
    void refetch();
  } catch (error) {
    toast({
      title: "Failed to create key",
      description: getErrorMessage(error),
      variant: "destructive",
    });
  }
};
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:49-63](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L49-L63), [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:144-201](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L144-L201)

> [!WARNING]
> Closing the creation dialog via `handleDialogClose` completely resets `newKey`, `newLabel`, and copy states back to their defaults.

```tsx
const handleDialogClose = (open: boolean) => {
  if (!open) {
    setNewKey("");
    setNewLabel("");
    setCopied(false);
  }
  setCreateOpen(open);
};
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:81-88](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L81-L88)

### Revocation and Toast Feedback Handling

Revoking an API key is initiated by clicking the trash action icon on a table row, which stores the target entity in `keyToRevoke`. Triggering `handleRevoke` issues an HTTP DELETE request to `API_KEY_ENDPOINTS.BY_ID(keyToRevoke.id)`, clears the revocation target, triggers a data refetch, and fires a success toast.

```tsx
const handleRevoke = async () => {
  if (!keyToRevoke) return;
  try {
    await api.delete(API_KEY_ENDPOINTS.BY_ID(keyToRevoke.id));
    toast({ title: "API key revoked", variant: "success" });
    setKeyToRevoke(null);
    void refetch();
  } catch (error) {
    toast({
      title: "Failed to revoke key",
      description: getErrorMessage(error),
      variant: "destructive",
    });
  }
};
```
Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:65-79](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L65-L79), [server/dashboard/src/utils/api-endpoints.ts:21-24](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts#L21-L24)

The dashboard error handling architecture maps exception responses across operations using specific utility functions. The following sequence traces execution paths for dialog rendering, error serialization, and toast notification delivery:

1. `ApiKeysPage` → `DialogContent` → `DialogOverlay`: Renders modal dialog layers with fixed positioning and background overlay styling.
   Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:140-140](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L140-L140), [server/dashboard/src/components/ui/dialog.tsx:17-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/dialog.tsx#L17-L39)
2. `ApiKeysPage` → `useApiQuery` → `run` → `getErrorMessage`: Intercepts query failures, extracts axios error details, and formats fallback strings.
   Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:37-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L37-L47), [server/dashboard/src/hooks/use-api-query.ts:31-38](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/hooks/use-api-query.ts#L31-L38), [server/dashboard/src/lib/error-message.ts:3-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/lib/error-message.ts#L3-L16)
3. `ApiKeysPage` → `useApiQuery` → `run` → `toast`: Dispatches formatted error notifications through the Sonner toast wrapper interface.
   Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:37-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L37-L47), [server/dashboard/src/hooks/use-api-query.ts:39-45](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/hooks/use-api-query.ts#L39-L45), [server/dashboard/src/components/ui/use-toast.ts:16-35](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/use-toast.ts#L16-L35)

```mermaid
sequenceDiagram
    participant ApiKeysPage as ApiKeysPage
    participant DialogContent as DialogContent
    participant DialogOverlay as DialogOverlay
    participant useApiQuery as useApiQuery
    participant run as run
    participant getErrorMessage as getErrorMessage
    participant toast as toast

    ApiKeysPage->>DialogContent: Render dialog container
    DialogContent->>DialogOverlay: Mount backdrop overlay
    ApiKeysPage->>useApiQuery: Initialize query hook
    useApiQuery->>run: Execute fetcher function
    run->>getErrorMessage: Parse caught error details
    run->>toast: Dispatch notification variant
```

Sources: [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:37-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L37-L47), [server/dashboard/src/app/root/dashboard/api-keys/page.tsx:140-140](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/api-keys/page.tsx#L140-L140), [server/dashboard/src/components/ui/dialog.tsx:17-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/dialog.tsx#L17-L39), [server/dashboard/src/hooks/use-api-query.ts:31-45](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/hooks/use-api-query.ts#L31-L45), [server/dashboard/src/lib/error-message.ts:3-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/lib/error-message.ts#L3-L16), [server/dashboard/src/components/ui/use-toast.ts:16-35](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/components/ui/use-toast.ts#L16-L35)

## Configuration and System Settings

### Provider Configuration Forms

The server configuration view provides administrative forms for managing LLM and embedding providers alongside user profile and credential controls.

The configuration page (`ConfigurationPage`) loads effective server settings from `MEMORY_ENDPOINTS.CONFIGURE` via `useApiQuery` and fetches supported provider lists from `MEMORY_ENDPOINTS.CONFIGURE_PROVIDERS`. The form manages provider identifiers, model names, and API keys for both LLM and embedding backends, restricting editing capabilities to users with administrator privileges (`isAdmin`). When saving, provider parameters are packaged into a versioned payload (`version: "v1.1"`) and posted back to the configure endpoint.

```typescript
type BundledProviders = {
  llm: string[];
  embedder: string[];
};
```
Sources: [server/dashboard/src/app/root/dashboard/configuration/page.tsx:27-30](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L27-L30), [server/dashboard/src/app/root/dashboard/configuration/page.tsx:41-57](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L41-L57), [server/dashboard/src/app/root/dashboard/configuration/page.tsx:71-98](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L71-L98)

> [!IMPORTANT]
> Selecting a new LLM provider automatically resets the associated API key state to an empty string to prevent credential leaks across provider boundaries.
Sources: [server/dashboard/src/app/root/dashboard/configuration/page.tsx:131-134](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L131-L134)

### User Profile and Password Mutations

The settings view (`SettingsPage`) manages user account details and password rotation through authenticated endpoints. Profile updates are submitted via `AUTH_ENDPOINTS.ME` using HTTP PATCH requests when input values differ from existing user state and contain non-whitespace characters. Password changes require verification of the current password, matching confirmation values, and a minimum length of 8 characters for the new password before submission to `AUTH_ENDPOINTS.CHANGE_PASSWORD`.

| Endpoint Constant | Path | Method | Purpose |
| :--- | :--- | :--- | :--- |
| `AUTH_ENDPOINTS.ME` | `/auth/me` | PATCH | Updates authenticated user name and email attributes |
| `AUTH_ENDPOINTS.CHANGE_PASSWORD` | `/auth/change-password` | POST | Rotates the user account password given current credentials |
| `MEMORY_ENDPOINTS.CONFIGURE` | `/configure` | GET / POST | Retrieves or persists server LLM and embedding provider settings |
| `MEMORY_ENDPOINTS.CONFIGURE_PROVIDERS` | `/configure/providers` | GET | Fetches lists of bundled LLM and embedder providers |

Sources: [server/dashboard/src/app/root/dashboard/configuration/page.tsx:43-52](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L43-L52), [server/dashboard/src/app/root/dashboard/configuration/page.tsx:97-97](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/configuration/page.tsx#L97-L97), [server/dashboard/src/app/root/dashboard/settings/page.tsx:43-46](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/settings/page.tsx#L43-L46), [server/dashboard/src/app/root/dashboard/settings/page.tsx:71-74](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/settings/page.tsx#L71-L74), [server/dashboard/src/utils/api-endpoints.ts:6-7](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts#L6-L7), [server/dashboard/src/utils/api-endpoints.ts:15-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts#L15-L16)

## Requests Audit Telemetry

### Telemetry Data Fetching and Metrics

The requests audit log view retrieves access logs from the self-hosted instance through `REQUEST_ENDPOINTS.BASE` (`/requests`) with a maximum query limit defined by `REQUEST_LOG_LIMIT` (200 records). Incoming `ApiRequestLog` entities are mapped via `normalizeLog` into structured `RequestLog` objects comprising unique identifiers, creation timestamps, HTTP methods, paths, status codes, latency measurements in milliseconds, and authentication source types. 

```typescript
type RequestLog = {
  id: string;
  createdAt: string;
  method: string;
  path: string;
  statusCode: number;
  latencyMs: number;
  authType: string;
};
```
Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:17-27](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L17-L27), [server/dashboard/src/app/root/dashboard/requests/page.tsx:71-81](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L71-L81), [server/dashboard/src/utils/api-endpoints.ts:26-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/utils/api-endpoints.ts#L26-L28)

Client-side calculations derive summary metrics from fetched logs including total request counts, successful requests (`statusCode < 400`), overall success percentage rates, and average latency values. Pagination divides the data stream into chunks governed by `PAGE_SIZE` (20 items per view).
Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:28-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L28-L28), [server/dashboard/src/app/root/dashboard/requests/page.tsx:103-114](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L103-L114)

> [!NOTE]
> Resetting the pagination page index to zero (`setPage(0)`) occurs automatically whenever the manual refresh button is triggered alongside query refetching.
Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:188-192](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L188-L192)

### Method and Status Tag Styling

Badge presentation utilizes distinct color styles based on HTTP request verbs and numerical response status codes. The `getMethodClassName` helper inspects normalized method strings case-insensitively, assigning sky-blue styles to `POST`, amber tones to `PUT` and `PATCH`, rose styling to `DELETE`, and fallback primary borders to unrecognized verbs.

| HTTP Method | Badge Theme Styling |
| :--- | :--- |
| `POST` | Sky blue (`border-sky-200 bg-sky-50 text-sky-700`) |
| `PUT`, `PATCH` | Amber (`border-amber-200 bg-amber-50 text-amber-700`) |
| `DELETE` | Rose (`border-rose-200 bg-rose-50 text-rose-700`) |
| Other / Default | Surface secondary (`border-memBorder-primary bg-surface-default-secondary`) |

Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:42-54](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L42-L54)

Similarly, `getStatusClassName` evaluates numeric HTTP response codes to apply error-severity styling: status codes of 500 and above render in rose tones, codes from 400 to 499 apply amber styling, and successful codes below 400 render with emerald green borders and background tints.
Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:30-40](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L30-L40)

### Authentication Source Inspection

The audit table inspects the `authType` property on incoming request entries to identify the verification mechanism used by the client. The `getAuthLabel` utility maps internal authentication identifiers to human-readable labels for presentation in the telemetry data grid.

| Raw Auth Type Value | Display Label |
| :--- | :--- |
| `bearer` | `JWT` |
| `api_key` | `API Key` |
| `admin_api_key` | `Admin Key` |
| `disabled` | `Disabled` |
| Any other value | `--` |

Sources: [server/dashboard/src/app/root/dashboard/requests/page.tsx:56-69](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/requests/page.tsx#L56-L69)

## Locked Features and Commercial Mockups

### Analytics Feature Wrapper

The self-hosted dashboard presents usage insights behind commercial wrappers via the `LockedPage` component. The analytics view specifies `utmMedium="dashboard-locked-analytics"`, rendering a description (`"Track memory operations, latency, and usage patterns over time."`) above an interactive visual mockup.

```typescript
export default function AnalyticsPage() {
  return (
    <LockedPage
      title="Analytics"
      description="Track memory operations, latency, and usage patterns over time."
      previewContent={<AnalyticsMockup />}
      utmMedium="dashboard-locked-analytics"
    />
  );
}
```
Sources: [server/dashboard/src/app/root/dashboard/analytics/page.tsx:45-54](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/analytics/page.tsx#L45-L54)

The `AnalyticsMockup` layout organizes metrics into two primary structural blocks: a top metric summary grid displaying statistical cards, followed by a time-series operations chart container.

| Stat Label | Mock Value | Card Container Style |
| :--- | :--- | :--- |
| `Total Operations` | `"12,847"` | `border-memBorder-primary` |
| `Avg Latency` | `"142ms"` | `border-memBorder-primary` |
| `Success Rate` | `"99.7%"` | `border-memBorder-primary` |

Sources: [server/dashboard/src/app/root/dashboard/analytics/page.tsx:9-24](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/analytics/page.tsx#L9-L24)

The operations chart renders a 200-pixel-tall flex container mapping twelve discrete height percentages (`[40, 65, 45, 80, 55, 90, 70, 85, 60, 95, 75, 50]`) to individual column elements styled with `bg-surface-default-brand rounded-t`.
Sources: [server/dashboard/src/app/root/dashboard/analytics/page.tsx:30-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/analytics/page.tsx#L30-L39)

> [!NOTE]
> All interactive inputs, buttons, and form controls within locked feature mockups are explicitly disabled (`disabled`) to indicate that the underlying feature requires a commercial license upgrade.
Sources: [server/dashboard/src/app/root/dashboard/webhooks/page.tsx:16-38](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/webhooks/page.tsx#L16-L38), [server/dashboard/src/app/root/dashboard/export/page.tsx:21-49](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/export/page.tsx#L21-L49)

### Webhooks and Export Mockup Configurations

The webhooks locked view uses `utmMedium="dashboard-locked-webhooks"` and presents a card containing an endpoint URL input field, a disabled checkbox list of event types, a masked signing secret field, and a submit button.

| Event Name | Checkbox Initial State |
| :--- | :--- |
| `memory.created` | Checked (`true`, disabled) |
| `memory.updated` | Unchecked (`false`, disabled) |
| `memory.deleted` | Unchecked (`false`, disabled) |
| `search.performed` | Unchecked (`false`, disabled) |

Sources: [server/dashboard/src/app/root/dashboard/webhooks/page.tsx:21-31](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/webhooks/page.tsx#L21-L31)

Similarly, the export locked view sets `utmMedium="dashboard-locked-export"` and exposes format options alongside a preview schema output box.

```json
{
  "memories": [
    {
      "id": "mem_abc123",
      "content": "User prefers dark mode",
      "user_id": "user_1",
      "created_at": "2026-04-10T12:00:00Z"
    }
  ],
  "total": 1247
}
```
Sources: [server/dashboard/src/app/root/dashboard/export/page.tsx:34-44](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/export/page.tsx#L34-L44)

The export format selector lists three format buttons (`JSON`, `CSV`, and `Pydantic Schema`), where the `JSON` button receives an active border highlight class (`border-memPurple-300`).
Sources: [server/dashboard/src/app/root/dashboard/export/page.tsx:16-26](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/server/dashboard/src/app/(root)/dashboard/export/page.tsx#L16-L26)

## Related

- [Dashboard Architecture](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/server-dashboard/dashboard-architecture)
- [Server API Endpoints](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/server-dashboard/server-api-endpoints)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/llms.txt) for all pages in this wiki.
