diff --git a/packages/api/methods.test.ts b/packages/api/methods.test.ts
index 9a9e2fb9ed31c41513596fd5482f2ba5b10395fd..8e0a9b586fa677f0dc68ed7641e9dc3ed8e33a29 100644
--- a/packages/api/methods.test.ts
+++ b/packages/api/methods.test.ts
@@ -58,6 +58,19 @@ describe('API CRUD operations', () => {
     await api.loadBudget(budgetName);
   });
 
+  // api: getBudgets
+  test('getBudgets', async () => {
+    const budgets = await api.getBudgets();
+    expect(budgets).toEqual(
+      expect.arrayContaining([
+        expect.objectContaining({
+          id: 'test-budget',
+          name: 'Default Test Db',
+        }),
+      ]),
+    );
+  });
+
   // apis: getCategoryGroups, createCategoryGroup, updateCategoryGroup, deleteCategoryGroup
   test('CategoryGroups: successfully update category groups', async () => {
     const month = '2023-10';
diff --git a/packages/api/methods.ts b/packages/api/methods.ts
index cc25bfe3e40983dbfdabded907f37c8f55f699ec..124d5d66628d7928d9c18eb02f1143bd7ac1f928 100644
--- a/packages/api/methods.ts
+++ b/packages/api/methods.ts
@@ -31,6 +31,10 @@ export async function downloadBudget(syncId, { password }: { password? } = {}) {
   return send('api/download-budget', { syncId, password });
 }
 
+export async function getBudgets() {
+  return send('api/get-budgets');
+}
+
 export async function sync() {
   return send('api/sync');
 }
diff --git a/packages/loot-core/src/server/api-models.ts b/packages/loot-core/src/server/api-models.ts
index 69be7a40a23456cd743193eb863121545538c8c4..ebd68e8d47f7f7f009fd43e530b4ffb3aa23a8f9 100644
--- a/packages/loot-core/src/server/api-models.ts
+++ b/packages/loot-core/src/server/api-models.ts
@@ -1,3 +1,4 @@
+import { Budget } from '../types/budget';
 import type {
   AccountEntity,
   CategoryEntity,
@@ -5,6 +6,7 @@ import type {
   PayeeEntity,
 } from '../types/models';
 
+import { RemoteFile } from './cloud-storage';
 import * as models from './models';
 
 export type APIAccountEntity = Pick<AccountEntity, 'id' | 'name'> & {
@@ -114,3 +116,39 @@ export const payeeModel = {
     return payee as PayeeEntity;
   },
 };
+
+export type APIFileEntity = Omit<RemoteFile, 'deleted' | 'fileId'> & {
+  id?: string;
+  cloudFileId: string;
+  state?: 'remote';
+};
+
+export const remoteFileModel = {
+  toExternal(file: RemoteFile): APIFileEntity | null {
+    if (file.deleted) {
+      return null;
+    }
+    return {
+      cloudFileId: file.fileId,
+      state: 'remote',
+      groupId: file.groupId,
+      name: file.name,
+      encryptKeyId: file.encryptKeyId,
+      hasKey: file.hasKey,
+    };
+  },
+
+  fromExternal(file: APIFileEntity) {
+    return { deleted: false, fileId: file.cloudFileId, ...file } as RemoteFile;
+  },
+};
+
+export const budgetModel = {
+  toExternal(file: Budget): APIFileEntity {
+    return file as APIFileEntity;
+  },
+
+  fromExternal(file: APIFileEntity) {
+    return file as Budget;
+  },
+};
diff --git a/packages/loot-core/src/server/api.ts b/packages/loot-core/src/server/api.ts
index fe670152ad4389eb9d9dd90d66b4f5226f1ab196..f2bbe5f42293b2879ee16a97c133b48ffcf86948 100644
--- a/packages/loot-core/src/server/api.ts
+++ b/packages/loot-core/src/server/api.ts
@@ -22,9 +22,11 @@ import { ServerHandlers } from '../types/server-handlers';
 import { addTransactions } from './accounts/sync';
 import {
   accountModel,
+  budgetModel,
   categoryModel,
   categoryGroupModel,
   payeeModel,
+  remoteFileModel,
 } from './api-models';
 import { runQuery as aqlQuery } from './aql';
 import * as cloudStorage from './cloud-storage';
@@ -226,6 +228,15 @@ handlers['api/download-budget'] = async function ({ syncId, password }) {
   await handlers['load-budget']({ id: result.id });
 };
 
+handlers['api/get-budgets'] = async function () {
+  const budgets = await handlers['get-budgets']();
+  const files = (await handlers['get-remote-files']()) || [];
+  return [
+    ...budgets.map(file => budgetModel.toExternal(file)),
+    ...files.map(file => remoteFileModel.toExternal(file)).filter(file => file),
+  ];
+};
+
 handlers['api/sync'] = async function () {
   const { id } = prefs.getPrefs();
   const result = await handlers['sync-budget']();
diff --git a/packages/loot-core/src/types/api-handlers.d.ts b/packages/loot-core/src/types/api-handlers.d.ts
index edd89582ddc3624f5eb679f0282895baa725b3bb..d8f23ae5be2db2efbc2071ba1d535844c370c552 100644
--- a/packages/loot-core/src/types/api-handlers.d.ts
+++ b/packages/loot-core/src/types/api-handlers.d.ts
@@ -3,6 +3,7 @@ import type {
   APIAccountEntity,
   APICategoryEntity,
   APICategoryGroupEntity,
+  APIFileEntity,
   APIPayeeEntity,
 } from '../server/api-models';
 
@@ -23,6 +24,8 @@ export interface ApiHandlers {
     password?: string;
   }) => Promise<void>;
 
+  'api/get-budgets': () => Promise<APIFileEntity[]>;
+
   'api/start-import': (arg: { budgetName: string }) => Promise<void>;
 
   'api/finish-import': () => Promise<void>;
diff --git a/upcoming-release-notes/2928.md b/upcoming-release-notes/2928.md
new file mode 100644
index 0000000000000000000000000000000000000000..3c3490058c9eee4f8a13c5ab3a728e1b4ac0c2c0
--- /dev/null
+++ b/upcoming-release-notes/2928.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [psybers]
+---
+
+API: add getBudgets() method to list all local/remote budgets.