diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 98ffaf03967e8e8385256e1e5d1c0841a71ff1a7..042fde70f8efb417b86a2969edc90e102999b889 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -12,8 +12,8 @@ const WorkspaceChat = lazy(() => import("./pages/WorkspaceChat"));
 const AdminUsers = lazy(() => import("./pages/Admin/Users"));
 const AdminInvites = lazy(() => import("./pages/Admin/Invitations"));
 const AdminWorkspaces = lazy(() => import("./pages/Admin/Workspaces"));
-const AdminChats = lazy(() => import("./pages/Admin/Chats"));
 const AdminSystem = lazy(() => import("./pages/Admin/System"));
+const GeneralChats = lazy(() => import("./pages/GeneralSettings/Chats"));
 const GeneralAppearance = lazy(() =>
   import("./pages/GeneralSettings/Appearance")
 );
@@ -77,6 +77,10 @@ export default function App() {
             path="/general/api-keys"
             element={<PrivateRoute Component={GeneralApiKeys} />}
           />
+          <Route
+            path="/general/workspace-chats"
+            element={<PrivateRoute Component={GeneralChats} />}
+          />
 
           {/* Admin Routes */}
           <Route
@@ -95,11 +99,6 @@ export default function App() {
             path="/admin/workspaces"
             element={<AdminRoute Component={AdminWorkspaces} />}
           />
-          <Route
-            path="/admin/workspace-chats"
-            element={<AdminRoute Component={AdminChats} />}
-          />
-
           {/* Onboarding Flow */}
           <Route path="/onboarding" element={<OnboardingFlow />} />
         </Routes>
diff --git a/frontend/src/components/SettingsSidebar/index.jsx b/frontend/src/components/SettingsSidebar/index.jsx
index c50ae878e367f31df9c7993b8857d96567dd743a..9b0c255312dcc942876653f305e36b83ae09e237 100644
--- a/frontend/src/components/SettingsSidebar/index.jsx
+++ b/frontend/src/components/SettingsSidebar/index.jsx
@@ -91,7 +91,7 @@ export default function SettingsSidebar() {
                       icon={<BookOpen className="h-5 w-5 flex-shrink-0" />}
                     />
                     <Option
-                      href={paths.admin.chats()}
+                      href={paths.general.chats()}
                       btnText="Workspace Chat"
                       icon={
                         <ChatCenteredText className="h-5 w-5 flex-shrink-0" />
@@ -131,6 +131,15 @@ export default function SettingsSidebar() {
                   btnText="Export or Import"
                   icon={<DownloadSimple className="h-5 w-5 flex-shrink-0" />}
                 />
+                {!user && (
+                  <Option
+                    href={paths.general.chats()}
+                    btnText="Chat History"
+                    icon={
+                      <ChatCenteredText className="h-5 w-5 flex-shrink-0" />
+                    }
+                  />
+                )}
                 <Option
                   href={paths.general.security()}
                   btnText="Security"
@@ -292,17 +301,17 @@ export function SidebarMobileHeader() {
                         btnText="Workspaces"
                         icon={<BookOpen className="h-5 w-5 flex-shrink-0" />}
                       />
-                      <Option
-                        href={paths.admin.chats()}
-                        btnText="Workspace Chat"
-                        icon={
-                          <ChatCenteredText className="h-5 w-5 flex-shrink-0" />
-                        }
-                      />
                     </>
                   )}
 
                   {/* General Settings */}
+                  <Option
+                    href={paths.general.chats()}
+                    btnText="Workspace Chat"
+                    icon={
+                      <ChatCenteredText className="h-5 w-5 flex-shrink-0" />
+                    }
+                  />
                   <Option
                     href={paths.general.appearance()}
                     btnText="Appearance"
diff --git a/frontend/src/models/admin.js b/frontend/src/models/admin.js
index a2a8746fb7d391cecf758dedc4ccd8fae00e1a44..ade884d58fcc5c2cc5b330b785d0fbed6b0ae15a 100644
--- a/frontend/src/models/admin.js
+++ b/frontend/src/models/admin.js
@@ -139,31 +139,6 @@ const Admin = {
       });
   },
 
-  // Workspace Chats Mgmt
-  chats: async (offset = 0) => {
-    return await fetch(`${API_BASE}/admin/workspace-chats`, {
-      method: "POST",
-      headers: baseHeaders(),
-      body: JSON.stringify({ offset }),
-    })
-      .then((res) => res.json())
-      .catch((e) => {
-        console.error(e);
-        return [];
-      });
-  },
-  deleteChat: async (chatId) => {
-    return await fetch(`${API_BASE}/admin/workspace-chats/${chatId}`, {
-      method: "DELETE",
-      headers: baseHeaders(),
-    })
-      .then((res) => res.json())
-      .catch((e) => {
-        console.error(e);
-        return { success: false, error: e.message };
-      });
-  },
-
   // System Preferences
   systemPreferences: async () => {
     return await fetch(`${API_BASE}/admin/system-preferences`, {
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js
index a90bddb236d29cc56f198fa028ab924e12850896..43f7a91829dec97a8c5d16eda930ef31c1cb1578 100644
--- a/frontend/src/models/system.js
+++ b/frontend/src/models/system.js
@@ -339,6 +339,40 @@ const System = {
         return { models: [], error: e.message };
       });
   },
+  chats: async (offset = 0) => {
+    return await fetch(`${API_BASE}/system/workspace-chats`, {
+      method: "POST",
+      headers: baseHeaders(),
+      body: JSON.stringify({ offset }),
+    })
+      .then((res) => res.json())
+      .catch((e) => {
+        console.error(e);
+        return [];
+      });
+  },
+  deleteChat: async (chatId) => {
+    return await fetch(`${API_BASE}/system/workspace-chats/${chatId}`, {
+      method: "DELETE",
+      headers: baseHeaders(),
+    })
+      .then((res) => res.json())
+      .catch((e) => {
+        console.error(e);
+        return { success: false, error: e.message };
+      });
+  },
+  exportChats: async () => {
+    return await fetch(`${API_BASE}/system/export-chats`, {
+      method: "GET",
+      headers: baseHeaders(),
+    })
+      .then((res) => res.text())
+      .catch((e) => {
+        console.error(e);
+        return null;
+      });
+  },
 };
 
 export default System;
diff --git a/frontend/src/pages/Admin/Chats/ChatRow/index.jsx b/frontend/src/pages/GeneralSettings/Chats/ChatRow/index.jsx
similarity index 97%
rename from frontend/src/pages/Admin/Chats/ChatRow/index.jsx
rename to frontend/src/pages/GeneralSettings/Chats/ChatRow/index.jsx
index 16e4dfaee6550d9665dc6abb4aaeedd7e45cb63c..96c3970d5a4607a58fe1382d99c69eaf763e84c4 100644
--- a/frontend/src/pages/Admin/Chats/ChatRow/index.jsx
+++ b/frontend/src/pages/GeneralSettings/Chats/ChatRow/index.jsx
@@ -1,7 +1,7 @@
 import { useRef } from "react";
-import Admin from "../../../../models/admin";
 import truncate from "truncate";
 import { X, Trash } from "@phosphor-icons/react";
+import System from "../../../../models/system";
 
 export default function ChatRow({ chat }) {
   const rowRef = useRef(null);
@@ -13,7 +13,7 @@ export default function ChatRow({ chat }) {
     )
       return false;
     rowRef?.current?.remove();
-    await Admin.deleteChat(chat.id);
+    await System.deleteChat(chat.id);
   };
 
   return (
diff --git a/frontend/src/pages/Admin/Chats/index.jsx b/frontend/src/pages/GeneralSettings/Chats/index.jsx
similarity index 75%
rename from frontend/src/pages/Admin/Chats/index.jsx
rename to frontend/src/pages/GeneralSettings/Chats/index.jsx
index 673e391084febbdee7924412661410547c3c1c92..3b2a1e95115afb34f538c6ffb4df88a62eddf774 100644
--- a/frontend/src/pages/Admin/Chats/index.jsx
+++ b/frontend/src/pages/GeneralSettings/Chats/index.jsx
@@ -5,12 +5,33 @@ import Sidebar, {
 import { isMobile } from "react-device-detect";
 import * as Skeleton from "react-loading-skeleton";
 import "react-loading-skeleton/dist/skeleton.css";
-import Admin from "../../../models/admin";
 import useQuery from "../../../hooks/useQuery";
 import ChatRow from "./ChatRow";
+import showToast from "../../../utils/toast";
+import System from "../../../models/system";
 
 const PAGE_SIZE = 20;
-export default function AdminChats() {
+export default function WorkspaceChats() {
+  const handleDumpChats = async () => {
+    const chats = await System.exportChats();
+    if (chats) {
+      const blob = new Blob([chats], { type: "application/jsonl" });
+      const link = document.createElement("a");
+      link.href = window.URL.createObjectURL(blob);
+      link.download = "chats.jsonl";
+      document.body.appendChild(link);
+      link.click();
+      window.URL.revokeObjectURL(link.href);
+      document.body.removeChild(link);
+      showToast(
+        "Chats exported successfully. Note: Must have at least 10 chats to be valid for OpenAI fine tuning.",
+        "success"
+      );
+    } else {
+      showToast("Failed to export chats.", "error");
+    }
+  };
+
   return (
     <div className="w-screen h-screen overflow-hidden bg-sidebar flex">
       {!isMobile && <Sidebar />}
@@ -25,6 +46,12 @@ export default function AdminChats() {
               <p className="text-2xl font-semibold text-white">
                 Workspace Chats
               </p>
+              <button
+                onClick={handleDumpChats}
+                className="border border-slate-200 px-4 py-1 rounded-lg text-slate-200 text-sm items-center flex gap-x-2 hover:bg-slate-200 hover:text-slate-800"
+              >
+                Export Chats to JSONL
+              </button>
             </div>
             <p className="text-sm font-base text-white text-opacity-60">
               These are all the recorded chats and messages that have been sent
@@ -54,7 +81,7 @@ function ChatsContainer() {
 
   useEffect(() => {
     async function fetchChats() {
-      const { chats: _chats, hasPages = false } = await Admin.chats(offset);
+      const { chats: _chats, hasPages = false } = await System.chats(offset);
       setChats(_chats);
       setCanNext(hasPages);
       setLoading(false);
@@ -105,9 +132,8 @@ function ChatsContainer() {
           </tr>
         </thead>
         <tbody>
-          {chats.map((chat) => (
-            <ChatRow key={chat.id} chat={chat} />
-          ))}
+          {!!chats &&
+            chats.map((chat) => <ChatRow key={chat.id} chat={chat} />)}
         </tbody>
       </table>
       <div className="flex w-full justify-between items-center">
diff --git a/frontend/src/utils/paths.js b/frontend/src/utils/paths.js
index 1d77abe5a449659098dd0f6aa0533ec20a961b43..cbe19795f45acace060139f0fa0619907434c11e 100644
--- a/frontend/src/utils/paths.js
+++ b/frontend/src/utils/paths.js
@@ -61,6 +61,9 @@ export default {
     apiKeys: () => {
       return "/general/api-keys";
     },
+    chats: () => {
+      return "/general/workspace-chats";
+    },
   },
   admin: {
     system: () => {
diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js
index a3852bd5ac66ea031eeac139dab632d82375ef11..23949d9223a8c5bea1aafc7f8916643873add506 100644
--- a/server/endpoints/admin.js
+++ b/server/endpoints/admin.js
@@ -251,56 +251,6 @@ function adminEndpoints(app) {
     }
   );
 
-  app.post(
-    "/admin/workspace-chats",
-    [validatedRequest],
-    async (request, response) => {
-      try {
-        const user = await userFromSession(request, response);
-        if (!user || user?.role !== "admin") {
-          response.sendStatus(401).end();
-          return;
-        }
-
-        const { offset = 0, limit = 20 } = reqBody(request);
-        const chats = await WorkspaceChats.whereWithData(
-          {},
-          limit,
-          offset * limit,
-          { id: "desc" }
-        );
-        const totalChats = await WorkspaceChats.count();
-        const hasPages = totalChats > (offset + 1) * limit;
-
-        response.status(200).json({ chats: chats, hasPages, totalChats });
-      } catch (e) {
-        console.error(e);
-        response.sendStatus(500).end();
-      }
-    }
-  );
-
-  app.delete(
-    "/admin/workspace-chats/:id",
-    [validatedRequest],
-    async (request, response) => {
-      try {
-        const user = await userFromSession(request, response);
-        if (!user || user?.role !== "admin") {
-          response.sendStatus(401).end();
-          return;
-        }
-
-        const { id } = request.params;
-        await WorkspaceChats.delete({ id: Number(id) });
-        response.status(200).json({ success, error });
-      } catch (e) {
-        console.error(e);
-        response.sendStatus(500).end();
-      }
-    }
-  );
-
   app.get(
     "/admin/system-preferences",
     [validatedRequest],
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index 7e565874d84c7a3c570f11e08b85bfe6415a0a6f..202ba3762c7d37978fd0324144d22aaeb8f41701 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -38,6 +38,8 @@ const { Telemetry } = require("../models/telemetry");
 const { WelcomeMessages } = require("../models/welcomeMessages");
 const { ApiKey } = require("../models/apiKeys");
 const { getCustomModels } = require("../utils/helpers/customModels");
+const { WorkspaceChats } = require("../models/workspaceChats");
+const { Workspace } = require("../models/workspace");
 
 function systemEndpoints(app) {
   if (!app) return;
@@ -646,6 +648,134 @@ function systemEndpoints(app) {
       }
     }
   );
+
+  app.post(
+    "/system/workspace-chats",
+    [validatedRequest],
+    async (request, response) => {
+      try {
+        if (
+          response.locals.multiUserMode &&
+          response.locals.user?.role !== "admin"
+        ) {
+          return response.sendStatus(401).end();
+        }
+
+        const { offset = 0, limit = 20 } = reqBody(request);
+        const chats = await WorkspaceChats.whereWithData(
+          {},
+          limit,
+          offset * limit,
+          { id: "desc" }
+        );
+        const totalChats = await WorkspaceChats.count();
+        const hasPages = totalChats > (offset + 1) * limit;
+
+        response.status(200).json({ chats: chats, hasPages, totalChats });
+      } catch (e) {
+        console.error(e);
+        response.sendStatus(500).end();
+      }
+    }
+  );
+
+  app.delete(
+    "/system/workspace-chats/:id",
+    [validatedRequest],
+    async (request, response) => {
+      try {
+        if (
+          response.locals.multiUserMode &&
+          response.locals.user?.role !== "admin"
+        ) {
+          return response.sendStatus(401).end();
+        }
+
+        const { id } = request.params;
+        await WorkspaceChats.delete({ id: Number(id) });
+        response.status(200).json({ success, error });
+      } catch (e) {
+        console.error(e);
+        response.sendStatus(500).end();
+      }
+    }
+  );
+
+  app.get(
+    "/system/export-chats",
+    [validatedRequest],
+    async (request, response) => {
+      try {
+        if (
+          response.locals.multiUserMode &&
+          response.locals.user?.role !== "admin"
+        ) {
+          return response.sendStatus(401).end();
+        }
+
+        const chats = await WorkspaceChats.whereWithData({}, null, null, {
+          id: "asc",
+        });
+        const workspaceIds = [
+          ...new Set(chats.map((chat) => chat.workspaceId)),
+        ];
+
+        const workspacesWithPrompts = await Promise.all(
+          workspaceIds.map((id) => Workspace.get({ id: Number(id) }))
+        );
+
+        const workspacePromptsMap = workspacesWithPrompts.reduce(
+          (acc, workspace) => {
+            acc[workspace.id] = workspace.openAiPrompt;
+            return acc;
+          },
+          {}
+        );
+
+        const workspaceChatsMap = chats.reduce((acc, chat) => {
+          const { prompt, response, workspaceId } = chat;
+          const responseJson = JSON.parse(response);
+
+          if (!acc[workspaceId]) {
+            acc[workspaceId] = {
+              messages: [
+                {
+                  role: "system",
+                  content:
+                    workspacePromptsMap[workspaceId] ||
+                    "Given the following conversation, relevant context, and a follow up question, reply with an answer to the current question the user is asking. Return only your response to the question given the above information following the users instructions as needed.",
+                },
+              ],
+            };
+          }
+
+          acc[workspaceId].messages.push(
+            {
+              role: "user",
+              content: prompt,
+            },
+            {
+              role: "assistant",
+              content: responseJson.text,
+            }
+          );
+
+          return acc;
+        }, {});
+
+        // Convert to JSONL
+        const jsonl = Object.values(workspaceChatsMap)
+          .map((workspaceChats) => JSON.stringify(workspaceChats))
+          .join("\n");
+
+        response.setHeader("Content-Type", "application/jsonl");
+        response.status(200).send(jsonl);
+      } catch (e) {
+        console.error(e);
+        response.sendStatus(500).end();
+      }
+    }
+  );
 }
 
 module.exports = { systemEndpoints };
diff --git a/server/models/workspaceChats.js b/server/models/workspaceChats.js
index 36703efa40f5814182e1a33356c5a6fefd5f9c7f..6dfbafeffe46e828b684e7890bb97148c0ec54d4 100644
--- a/server/models/workspaceChats.js
+++ b/server/models/workspaceChats.js
@@ -161,7 +161,7 @@ const WorkspaceChats = {
         const user = await User.get({ id: res.user_id });
         res.user = user
           ? { username: user.username }
-          : { username: "deleted user" };
+          : { username: "unknown user" };
       }
 
       return results;