diff --git a/open-api/bin/generate-open-api.sh b/open-api/bin/generate-open-api.sh
index 76012383cf..f0a211abe4 100755
--- a/open-api/bin/generate-open-api.sh
+++ b/open-api/bin/generate-open-api.sh
@@ -19,7 +19,7 @@ function dart {
 function typescript {
   rm -rf ./typescript-sdk/client
   npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/axios-client --additional-properties=useSingleRequestParameter=true,supportsES6=true
-  npx --yes oazapfts --optimistic --argumentStyle=object immich-openapi-specs.json typescript-sdk/fetch-client.ts
+  npx --yes oazapfts --optimistic --argumentStyle=object --useEnumType immich-openapi-specs.json typescript-sdk/fetch-client.ts
   npm --prefix typescript-sdk ci && npm --prefix typescript-sdk run build
 }
 
diff --git a/open-api/typescript-sdk/fetch-client.ts b/open-api/typescript-sdk/fetch-client.ts
index 00b8c68326..e37b43ca79 100644
Binary files a/open-api/typescript-sdk/fetch-client.ts and b/open-api/typescript-sdk/fetch-client.ts differ
diff --git a/open-api/typescript-sdk/tsconfig.fetch.json b/open-api/typescript-sdk/tsconfig.fetch.json
index 58ef1ffa6b..92d17ebda9 100644
--- a/open-api/typescript-sdk/tsconfig.fetch.json
+++ b/open-api/typescript-sdk/tsconfig.fetch.json
@@ -1,5 +1,5 @@
 {
-  "include": ["fetch.ts"],
+  "include": ["fetch.ts", "fetch-client.ts"],
   "compilerOptions": {
     "target": "esnext",
     "strict": true,
diff --git a/web/src/api/index.ts b/web/src/api/index.ts
deleted file mode 100644
index 886f439d8e..0000000000
--- a/web/src/api/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './api';
-export * from '@immich/sdk/axios';
-export * from './utils';
diff --git a/web/src/api/types.ts b/web/src/api/types.ts
deleted file mode 100644
index 7a2ae17f67..0000000000
--- a/web/src/api/types.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { Configuration } from '@immich/sdk/axios';
-
-/* eslint-disable @typescript-eslint/no-explicit-any */
-export type ApiFp = (configuration: Configuration) => Record<any, (...arguments_: any) => any>;
-
-export type OmitLast<T extends readonly unknown[]> = T extends readonly [...infer U, any?] ? U : [...T];
-
-export type ApiParams<F extends ApiFp, K extends keyof ReturnType<F>> = OmitLast<Parameters<ReturnType<F>[K]>>;
diff --git a/web/src/api/utils.ts b/web/src/api/utils.ts
deleted file mode 100644
index decfefc560..0000000000
--- a/web/src/api/utils.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { finishOAuth, linkOAuthAccount, startOAuth, unlinkOAuthAccount } from '@immich/sdk';
-import { type UserResponseDto } from '@immich/sdk/axios';
-import type { AxiosError } from 'axios';
-import {
-  NotificationType,
-  notificationController,
-} from '../lib/components/shared-components/notification/notification';
-import { handleError } from '../lib/utils/handle-error';
-
-export type ApiError = AxiosError<{ message: string }>;
-
-export const copyToClipboard = async (secret: string) => {
-  try {
-    await navigator.clipboard.writeText(secret);
-    notificationController.show({ message: 'Copied to clipboard!', type: NotificationType.Info });
-  } catch (error) {
-    handleError(error, 'Cannot copy to clipboard, make sure you are accessing the page through https');
-  }
-};
-
-export const makeSharedLinkUrl = (externalDomain: string, key: string) => {
-  let url = externalDomain || window.location.origin;
-  if (!url.endsWith('/')) {
-    url += '/';
-  }
-  return `${url}share/${key}`;
-};
-
-export const oauth = {
-  isCallback: (location: Location) => {
-    const search = location.search;
-    return search.includes('code=') || search.includes('error=');
-  },
-  isAutoLaunchDisabled: (location: Location) => {
-    const values = ['autoLaunch=0', 'password=1', 'password=true'];
-    for (const value of values) {
-      if (location.search.includes(value)) {
-        return true;
-      }
-    }
-    return false;
-  },
-  authorize: async (location: Location) => {
-    try {
-      const redirectUri = location.href.split('?')[0];
-      const { url } = await startOAuth({ oAuthConfigDto: { redirectUri } });
-      window.location.href = url;
-      return true;
-    } catch (error) {
-      handleError(error, 'Unable to login with OAuth');
-      return false;
-    }
-  },
-  login: (location: Location) => {
-    return finishOAuth({ oAuthCallbackDto: { url: location.href } });
-  },
-  link: (location: Location): Promise<UserResponseDto> => {
-    return linkOAuthAccount({ oAuthCallbackDto: { url: location.href } });
-  },
-  unlink: () => {
-    return unlinkOAuthAccount();
-  },
-};
diff --git a/web/src/api/api.ts b/web/src/lib/api/index.ts
similarity index 57%
rename from web/src/api/api.ts
rename to web/src/lib/api/index.ts
index 53340cb455..de8a5f722f 100644
--- a/web/src/api/api.ts
+++ b/web/src/lib/api/index.ts
@@ -4,12 +4,10 @@ class ImmichApi {
   public downloadApi: DownloadApi;
   public assetApi: AssetApi;
 
-  private config: configuration.Configuration;
-
   constructor(parameters: configuration.ConfigurationParameters) {
-    this.config = new configuration.Configuration(parameters);
-    this.downloadApi = new DownloadApi(this.config);
-    this.assetApi = new AssetApi(this.config);
+    const config = new configuration.Configuration(parameters);
+    this.downloadApi = new DownloadApi(config);
+    this.assetApi = new AssetApi(config);
   }
 }
 
diff --git a/web/src/lib/components/admin-page/jobs/job-tile.svelte b/web/src/lib/components/admin-page/jobs/job-tile.svelte
index 42f489d41d..9e47386692 100644
--- a/web/src/lib/components/admin-page/jobs/job-tile.svelte
+++ b/web/src/lib/components/admin-page/jobs/job-tile.svelte
@@ -3,8 +3,7 @@
   import Button from '$lib/components/elements/buttons/button.svelte';
   import Icon from '$lib/components/elements/icon.svelte';
   import { locale } from '$lib/stores/preferences.store';
-  import { type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk';
-  import { JobCommand } from '@immich/sdk/axios';
+  import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk';
   import {
     mdiAlertCircle,
     mdiAllInclusive,
diff --git a/web/src/lib/components/admin-page/jobs/jobs-panel.svelte b/web/src/lib/components/admin-page/jobs/jobs-panel.svelte
index 7ab7c0462a..60756166f2 100644
--- a/web/src/lib/components/admin-page/jobs/jobs-panel.svelte
+++ b/web/src/lib/components/admin-page/jobs/jobs-panel.svelte
@@ -6,8 +6,7 @@
   import { featureFlags } from '$lib/stores/server-config.store';
   import { getJobName } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { sendJobCommand, type AllJobStatusResponseDto, type JobCommandDto } from '@immich/sdk';
-  import { JobCommand, JobName } from '@immich/sdk/axios';
+  import { JobCommand, JobName, sendJobCommand, type AllJobStatusResponseDto, type JobCommandDto } from '@immich/sdk';
   import {
     mdiFaceRecognition,
     mdiFileJpgBox,
diff --git a/web/src/lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte b/web/src/lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte
index b0f5a9c088..cd73b77f44 100644
--- a/web/src/lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte
+++ b/web/src/lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte
@@ -1,7 +1,14 @@
 <script lang="ts">
   import Icon from '$lib/components/elements/icon.svelte';
-  import { type SystemConfigDto } from '@immich/sdk';
-  import { AudioCodec, CQMode, ToneMapping, TranscodeHWAccel, TranscodePolicy, VideoCodec } from '@immich/sdk/axios';
+  import {
+    AudioCodec,
+    CQMode,
+    ToneMapping,
+    TranscodeHWAccel,
+    TranscodePolicy,
+    VideoCodec,
+    type SystemConfigDto,
+  } from '@immich/sdk';
   import { mdiHelpCircleOutline } from '@mdi/js';
   import { isEqual, sortBy } from 'lodash-es';
   import { createEventDispatcher } from 'svelte';
diff --git a/web/src/lib/components/admin-page/settings/job-settings/job-settings.svelte b/web/src/lib/components/admin-page/settings/job-settings/job-settings.svelte
index 146ff16c13..d3315f18a8 100644
--- a/web/src/lib/components/admin-page/settings/job-settings/job-settings.svelte
+++ b/web/src/lib/components/admin-page/settings/job-settings/job-settings.svelte
@@ -1,7 +1,6 @@
 <script lang="ts">
   import { getJobName } from '$lib/utils';
-  import { type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk';
-  import { JobName } from '@immich/sdk/axios';
+  import { JobName, type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk';
   import { isEqual } from 'lodash-es';
   import { createEventDispatcher } from 'svelte';
   import { fade } from 'svelte/transition';
@@ -29,7 +28,8 @@
     JobName.Migration,
   ];
 
-  function isSystemConfigJobDto(jobName: JobName): jobName is keyof SystemConfigJobDto {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  function isSystemConfigJobDto(jobName: any): jobName is keyof SystemConfigJobDto {
     return jobName in config.job;
   }
 </script>
diff --git a/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte b/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte
index 85ea60545c..f29e6f9eaf 100644
--- a/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte
+++ b/web/src/lib/components/admin-page/settings/logging-settings/logging-settings.svelte
@@ -1,6 +1,5 @@
 <script lang="ts">
-  import { type SystemConfigDto } from '@immich/sdk';
-  import { LogLevel } from '@immich/sdk/axios';
+  import { LogLevel, type SystemConfigDto } from '@immich/sdk';
   import { isEqual } from 'lodash-es';
   import { createEventDispatcher } from 'svelte';
   import { fade } from 'svelte/transition';
diff --git a/web/src/lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte b/web/src/lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte
index 8f06d17b79..4c63380fda 100644
--- a/web/src/lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte
+++ b/web/src/lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte
@@ -1,8 +1,7 @@
 <script lang="ts">
   import SettingButtonsRow from '$lib/components/admin-page/settings/setting-buttons-row.svelte';
   import SettingSelect from '$lib/components/admin-page/settings/setting-select.svelte';
-  import { type SystemConfigDto } from '@immich/sdk';
-  import { Colorspace } from '@immich/sdk/axios';
+  import { Colorspace, type SystemConfigDto } from '@immich/sdk';
   import { isEqual } from 'lodash-es';
   import { createEventDispatcher } from 'svelte';
   import { fade } from 'svelte/transition';
diff --git a/web/src/lib/components/album-page/__tests__/album-card.spec.ts b/web/src/lib/components/album-page/__tests__/album-card.spec.ts
index bbcd2f5c6a..08285e7d37 100644
--- a/web/src/lib/components/album-page/__tests__/album-card.spec.ts
+++ b/web/src/lib/components/album-page/__tests__/album-card.spec.ts
@@ -1,12 +1,13 @@
 import { createObjectURLMock } from '$lib/__mocks__/jsdom-url.mock';
-import { api, ThumbnailFormat } from '@api';
+import { api } from '$lib/api';
+import { ThumbnailFormat } from '@immich/sdk';
 import { albumFactory } from '@test-data';
 import '@testing-library/jest-dom';
-import { fireEvent, render, type RenderResult, waitFor } from '@testing-library/svelte';
-import AlbumCard from '../album-card.svelte';
+import { fireEvent, render, waitFor, type RenderResult } from '@testing-library/svelte';
 import type { MockedObject } from 'vitest';
+import AlbumCard from '../album-card.svelte';
 
-vi.mock('@api');
+vi.mock('$lib/api');
 const apiMock: MockedObject<typeof api> = api as MockedObject<typeof api>;
 
 describe('AlbumCard component', () => {
diff --git a/web/src/lib/components/album-page/album-card.svelte b/web/src/lib/components/album-page/album-card.svelte
index 609dc1ce3a..400c7fcfcd 100644
--- a/web/src/lib/components/album-page/album-card.svelte
+++ b/web/src/lib/components/album-page/album-card.svelte
@@ -1,11 +1,11 @@
 <script lang="ts">
+  import { api } from '$lib/api';
   import noThumbnailUrl from '$lib/assets/no-thumbnail.png';
   import Icon from '$lib/components/elements/icon.svelte';
   import { locale } from '$lib/stores/preferences.store';
   import { user } from '$lib/stores/user.store';
   import { getAssetThumbnailUrl } from '$lib/utils';
-  import { ThumbnailFormat, api, type AlbumResponseDto } from '@api';
-  import { getUserById } from '@immich/sdk';
+  import { ThumbnailFormat, getUserById, type AlbumResponseDto } from '@immich/sdk';
   import { mdiDotsVertical } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import { getContextMenuPosition } from '../../utils/context-menu';
diff --git a/web/src/lib/components/album-page/album-options.svelte b/web/src/lib/components/album-page/album-options.svelte
index 53af9ec764..df50833b1b 100644
--- a/web/src/lib/components/album-page/album-options.svelte
+++ b/web/src/lib/components/album-page/album-options.svelte
@@ -1,12 +1,12 @@
 <script lang="ts">
+  import Icon from '$lib/components/elements/icon.svelte';
+  import type { AlbumResponseDto, UserResponseDto } from '@immich/sdk';
   import { mdiClose, mdiPlus } from '@mdi/js';
+  import { createEventDispatcher } from 'svelte';
   import SettingSwitch from '../admin-page/settings/setting-switch.svelte';
   import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
   import FullScreenModal from '../shared-components/full-screen-modal.svelte';
   import UserAvatar from '../shared-components/user-avatar.svelte';
-  import { createEventDispatcher } from 'svelte';
-  import type { AlbumResponseDto, UserResponseDto } from '@api';
-  import Icon from '$lib/components/elements/icon.svelte';
 
   export let album: AlbumResponseDto;
   export let user: UserResponseDto;
diff --git a/web/src/lib/components/album-page/album-viewer.svelte b/web/src/lib/components/album-page/album-viewer.svelte
index 9777cd1f5b..e7bb18272f 100644
--- a/web/src/lib/components/album-page/album-viewer.svelte
+++ b/web/src/lib/components/album-page/album-viewer.svelte
@@ -5,7 +5,7 @@
   import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store';
   import { locale } from '$lib/stores/preferences.store';
   import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
-  import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@api';
+  import type { AlbumResponseDto, SharedLinkResponseDto, UserResponseDto } from '@immich/sdk';
   import { onDestroy, onMount } from 'svelte';
   import { dateFormats } from '../../constants';
   import { createAssetInteractionStore } from '../../stores/asset-interaction.store';
diff --git a/web/src/lib/components/album-page/share-info-modal.svelte b/web/src/lib/components/album-page/share-info-modal.svelte
index d3ce13cb2d..d26541764d 100644
--- a/web/src/lib/components/album-page/share-info-modal.svelte
+++ b/web/src/lib/components/album-page/share-info-modal.svelte
@@ -1,6 +1,5 @@
 <script lang="ts">
-  import { type AlbumResponseDto, type UserResponseDto } from '@immich/sdk';
-  import { getMyUserInfo, removeUserFromAlbum } from '@immich/sdk';
+  import { getMyUserInfo, removeUserFromAlbum, type AlbumResponseDto, type UserResponseDto } from '@immich/sdk';
   import { mdiDotsVertical } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import { getContextMenuPosition } from '../../utils/context-menu';
diff --git a/web/src/lib/components/album-page/thumbnail-selection.svelte b/web/src/lib/components/album-page/thumbnail-selection.svelte
index f098fbf69a..c12abc8917 100644
--- a/web/src/lib/components/album-page/thumbnail-selection.svelte
+++ b/web/src/lib/components/album-page/thumbnail-selection.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { AlbumResponseDto, AssetResponseDto } from '@api';
+  import type { AlbumResponseDto, AssetResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import { quintOut } from 'svelte/easing';
   import { fly } from 'svelte/transition';
diff --git a/web/src/lib/components/asset-viewer/activity-status.svelte b/web/src/lib/components/asset-viewer/activity-status.svelte
index 8e1aa91af9..02d37c41da 100644
--- a/web/src/lib/components/asset-viewer/activity-status.svelte
+++ b/web/src/lib/components/asset-viewer/activity-status.svelte
@@ -1,8 +1,8 @@
 <script lang="ts">
+  import type { ActivityResponseDto } from '@immich/sdk';
   import { mdiCommentOutline, mdiHeart, mdiHeartOutline } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import Icon from '../elements/icon.svelte';
-  import type { ActivityResponseDto } from '@api';
 
   export let isLiked: ActivityResponseDto | null;
   export let numberOfComments: number | undefined;
diff --git a/web/src/lib/components/asset-viewer/activity-viewer.svelte b/web/src/lib/components/asset-viewer/activity-viewer.svelte
index 9c075bd64e..f102a980ba 100644
--- a/web/src/lib/components/asset-viewer/activity-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/activity-viewer.svelte
@@ -8,6 +8,8 @@
   import { handleError } from '$lib/utils/handle-error';
   import { isTenMinutesApart } from '$lib/utils/timesince';
   import {
+    ReactionType,
+    ThumbnailFormat,
     createActivity,
     deleteActivity,
     getActivities,
@@ -15,7 +17,6 @@
     type AssetTypeEnum,
     type UserResponseDto,
   } from '@immich/sdk';
-  import { ReactionType, ThumbnailFormat } from '@immich/sdk/axios';
   import { mdiClose, mdiDotsVertical, mdiHeart, mdiSend } from '@mdi/js';
   import * as luxon from 'luxon';
   import { createEventDispatcher, onMount } from 'svelte';
diff --git a/web/src/lib/components/asset-viewer/album-list-item.svelte b/web/src/lib/components/asset-viewer/album-list-item.svelte
index 175647d6e1..f2cb181e4c 100644
--- a/web/src/lib/components/asset-viewer/album-list-item.svelte
+++ b/web/src/lib/components/asset-viewer/album-list-item.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
   import { getAssetThumbnailUrl } from '$lib/utils';
-  import { ThumbnailFormat, type AlbumResponseDto } from '@api';
+  import { ThumbnailFormat, type AlbumResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
 
   const dispatch = createEventDispatcher<{
diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
index a04ac48c58..fe5d14d809 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
@@ -5,7 +5,7 @@
   import { getAssetJobName } from '$lib/utils';
   import { clickOutside } from '$lib/utils/click-outside';
   import { getContextMenuPosition } from '$lib/utils/context-menu';
-  import { AssetJobName, AssetTypeEnum, type AssetResponseDto } from '@api';
+  import { AssetJobName, AssetTypeEnum, type AssetResponseDto } from '@immich/sdk';
   import {
     mdiAlertOutline,
     mdiArrowLeft,
diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte
index f8e5a1dbba..1baabc9280 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte
@@ -20,12 +20,6 @@
     AssetJobName,
     AssetTypeEnum,
     ReactionType,
-    type ActivityResponseDto,
-    type AlbumResponseDto,
-    type AssetResponseDto,
-    type SharedLinkResponseDto,
-  } from '@api';
-  import {
     createActivity,
     createAlbum,
     deleteActivity,
@@ -36,6 +30,10 @@
     runAssetJobs,
     updateAsset,
     updateAssets,
+    type ActivityResponseDto,
+    type AlbumResponseDto,
+    type AssetResponseDto,
+    type SharedLinkResponseDto,
   } from '@immich/sdk';
   import { mdiChevronLeft, mdiChevronRight, mdiImageBrokenVariant } from '@mdi/js';
   import { createEventDispatcher, onDestroy, onMount } from 'svelte';
diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte
index 757bfe3956..252119a0aa 100644
--- a/web/src/lib/components/asset-viewer/detail-panel.svelte
+++ b/web/src/lib/components/asset-viewer/detail-panel.svelte
@@ -11,8 +11,13 @@
   import { getAssetFilename } from '$lib/utils/asset-utils';
   import { autoGrowHeight } from '$lib/utils/autogrow';
   import { clickOutside } from '$lib/utils/click-outside';
-  import { ThumbnailFormat, type AlbumResponseDto, type AssetResponseDto } from '@api';
-  import { getAssetInfo, updateAsset } from '@immich/sdk';
+  import {
+    ThumbnailFormat,
+    getAssetInfo,
+    updateAsset,
+    type AlbumResponseDto,
+    type AssetResponseDto,
+  } from '@immich/sdk';
   import {
     mdiCalendar,
     mdiCameraIris,
diff --git a/web/src/lib/components/asset-viewer/panorama-viewer.svelte b/web/src/lib/components/asset-viewer/panorama-viewer.svelte
index 787f3a39de..41b2755eaa 100644
--- a/web/src/lib/components/asset-viewer/panorama-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/panorama-viewer.svelte
@@ -1,8 +1,9 @@
 <script lang="ts">
+  import { api } from '$lib/api';
+  import { getKey } from '$lib/utils';
+  import { type AssetResponseDto } from '@immich/sdk';
   import { fade } from 'svelte/transition';
   import LoadingSpinner from '../shared-components/loading-spinner.svelte';
-  import { api, type AssetResponseDto } from '@api';
-  import { getKey } from '$lib/utils';
 
   export let asset: AssetResponseDto;
 
diff --git a/web/src/lib/components/asset-viewer/photo-viewer.svelte b/web/src/lib/components/asset-viewer/photo-viewer.svelte
index fdb1d9bb81..e10d5573ca 100644
--- a/web/src/lib/components/asset-viewer/photo-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/photo-viewer.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import { api } from '$lib/api';
   import { photoViewer } from '$lib/stores/assets.store';
   import { boundingBoxesArray } from '$lib/stores/people.store';
   import { alwaysLoadOriginalFile } from '$lib/stores/preferences.store';
@@ -7,7 +8,7 @@
   import { isWebCompatibleImage } from '$lib/utils/asset-utils';
   import { getBoundingBox } from '$lib/utils/people-utils';
   import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
-  import { api, type AssetResponseDto } from '@api';
+  import { type AssetResponseDto } from '@immich/sdk';
   import { useZoomImageWheel } from '@zoom-image/svelte';
   import { onDestroy, onMount } from 'svelte';
   import { fade } from 'svelte/transition';
diff --git a/web/src/lib/components/asset-viewer/video-viewer.svelte b/web/src/lib/components/asset-viewer/video-viewer.svelte
index bbcfd7a126..96713d6217 100644
--- a/web/src/lib/components/asset-viewer/video-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/video-viewer.svelte
@@ -2,7 +2,7 @@
   import { videoViewerVolume } from '$lib/stores/preferences.store';
   import { getAssetFileUrl, getAssetThumbnailUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { ThumbnailFormat } from '@api';
+  import { ThumbnailFormat } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import { fade } from 'svelte/transition';
   import LoadingSpinner from '../shared-components/loading-spinner.svelte';
diff --git a/web/src/lib/components/assets/thumbnail/thumbnail.svelte b/web/src/lib/components/assets/thumbnail/thumbnail.svelte
index f8bea7b58b..ec511d4192 100644
--- a/web/src/lib/components/assets/thumbnail/thumbnail.svelte
+++ b/web/src/lib/components/assets/thumbnail/thumbnail.svelte
@@ -4,7 +4,7 @@
   import { ProjectionType } from '$lib/constants';
   import { getAssetFileUrl, getAssetThumbnailUrl, isSharedLink } from '$lib/utils';
   import { timeToSeconds } from '$lib/utils/time-to-seconds';
-  import { AssetTypeEnum, ThumbnailFormat, type AssetResponseDto } from '@api';
+  import { AssetTypeEnum, ThumbnailFormat, type AssetResponseDto } from '@immich/sdk';
   import {
     mdiArchiveArrowDownOutline,
     mdiCameraBurst,
diff --git a/web/src/lib/components/faces-page/assign-face-side-panel.svelte b/web/src/lib/components/faces-page/assign-face-side-panel.svelte
index be29759c05..6b8d8af174 100644
--- a/web/src/lib/components/faces-page/assign-face-side-panel.svelte
+++ b/web/src/lib/components/faces-page/assign-face-side-panel.svelte
@@ -4,8 +4,13 @@
   import { getAssetThumbnailUrl, getPeopleThumbnailUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
   import { getPersonNameWithHiddenValue, searchNameLocal } from '$lib/utils/person';
-  import { AssetTypeEnum, ThumbnailFormat, type AssetFaceResponseDto, type PersonResponseDto } from '@api';
-  import { searchPerson } from '@immich/sdk';
+  import {
+    AssetTypeEnum,
+    ThumbnailFormat,
+    searchPerson,
+    type AssetFaceResponseDto,
+    type PersonResponseDto,
+  } from '@immich/sdk';
   import { mdiArrowLeftThin, mdiClose, mdiMagnify, mdiPlus } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import { linear } from 'svelte/easing';
diff --git a/web/src/lib/components/faces-page/edit-name-input.svelte b/web/src/lib/components/faces-page/edit-name-input.svelte
index 139a5a8325..fa968e6914 100644
--- a/web/src/lib/components/faces-page/edit-name-input.svelte
+++ b/web/src/lib/components/faces-page/edit-name-input.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import { type PersonResponseDto } from '@api';
+  import { type PersonResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
   import Button from '../elements/buttons/button.svelte';
diff --git a/web/src/lib/components/faces-page/face-thumbnail.svelte b/web/src/lib/components/faces-page/face-thumbnail.svelte
index 2ed2e3049a..e1c6ab154e 100644
--- a/web/src/lib/components/faces-page/face-thumbnail.svelte
+++ b/web/src/lib/components/faces-page/face-thumbnail.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
   import { getPeopleThumbnailUrl } from '$lib/utils';
-  import { type PersonResponseDto } from '@api';
+  import { type PersonResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
 
diff --git a/web/src/lib/components/faces-page/merge-face-selector.svelte b/web/src/lib/components/faces-page/merge-face-selector.svelte
index 72cea4bac6..434bfb88ae 100644
--- a/web/src/lib/components/faces-page/merge-face-selector.svelte
+++ b/web/src/lib/components/faces-page/merge-face-selector.svelte
@@ -4,8 +4,7 @@
   import Icon from '$lib/components/elements/icon.svelte';
   import { ActionQueryParameterValue, AppRoute, QueryParameter } from '$lib/constants';
   import { handleError } from '$lib/utils/handle-error';
-  import { type PersonResponseDto } from '@api';
-  import { getAllPeople, getPerson, mergePerson } from '@immich/sdk';
+  import { getAllPeople, getPerson, mergePerson, type PersonResponseDto } from '@immich/sdk';
   import { mdiCallMerge, mdiMerge, mdiSwapHorizontal } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import { flip } from 'svelte/animate';
diff --git a/web/src/lib/components/faces-page/merge-suggestion-modal.svelte b/web/src/lib/components/faces-page/merge-suggestion-modal.svelte
index 0b7dfdca22..892ec6908f 100644
--- a/web/src/lib/components/faces-page/merge-suggestion-modal.svelte
+++ b/web/src/lib/components/faces-page/merge-suggestion-modal.svelte
@@ -2,7 +2,7 @@
   import Icon from '$lib/components/elements/icon.svelte';
   import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
   import { getPeopleThumbnailUrl } from '$lib/utils';
-  import { type PersonResponseDto } from '@api';
+  import { type PersonResponseDto } from '@immich/sdk';
   import { mdiArrowLeft, mdiClose, mdiMerge } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
diff --git a/web/src/lib/components/faces-page/people-card.svelte b/web/src/lib/components/faces-page/people-card.svelte
index 730711091e..4bb4947127 100644
--- a/web/src/lib/components/faces-page/people-card.svelte
+++ b/web/src/lib/components/faces-page/people-card.svelte
@@ -3,7 +3,7 @@
   import { AppRoute, QueryParameter } from '$lib/constants';
   import { getPeopleThumbnailUrl } from '$lib/utils';
   import { getContextMenuPosition } from '$lib/utils/context-menu';
-  import { type PersonResponseDto } from '@api';
+  import { type PersonResponseDto } from '@immich/sdk';
   import { mdiDotsVertical } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte';
diff --git a/web/src/lib/components/faces-page/people-list.svelte b/web/src/lib/components/faces-page/people-list.svelte
index d7f6ccb2d7..609d103bb0 100644
--- a/web/src/lib/components/faces-page/people-list.svelte
+++ b/web/src/lib/components/faces-page/people-list.svelte
@@ -2,8 +2,7 @@
   import { maximumLengthSearchPeople, timeBeforeShowLoadingSpinner } from '$lib/constants';
   import { handleError } from '$lib/utils/handle-error';
   import { searchNameLocal } from '$lib/utils/person';
-  import { type PersonResponseDto } from '@api';
-  import { searchPerson } from '@immich/sdk';
+  import { searchPerson, type PersonResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import FaceThumbnail from './face-thumbnail.svelte';
   import SearchBar from './search-bar.svelte';
diff --git a/web/src/lib/components/faces-page/person-side-panel.svelte b/web/src/lib/components/faces-page/person-side-panel.svelte
index 0aa716fe4c..a34ee322f6 100644
--- a/web/src/lib/components/faces-page/person-side-panel.svelte
+++ b/web/src/lib/components/faces-page/person-side-panel.svelte
@@ -6,8 +6,15 @@
   import { getPeopleThumbnailUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
   import { getPersonNameWithHiddenValue } from '$lib/utils/person';
-  import { AssetTypeEnum, type AssetFaceResponseDto, type PersonResponseDto } from '@api';
-  import { createPerson, getAllPeople, getFaces, reassignFacesById } from '@immich/sdk';
+  import {
+    AssetTypeEnum,
+    createPerson,
+    getAllPeople,
+    getFaces,
+    reassignFacesById,
+    type AssetFaceResponseDto,
+    type PersonResponseDto,
+  } from '@immich/sdk';
   import { mdiArrowLeftThin, mdiRestart } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import { linear } from 'svelte/easing';
diff --git a/web/src/lib/components/forms/api-key-form.svelte b/web/src/lib/components/forms/api-key-form.svelte
index f9588b38f6..53283d9b91 100644
--- a/web/src/lib/components/forms/api-key-form.svelte
+++ b/web/src/lib/components/forms/api-key-form.svelte
@@ -1,13 +1,13 @@
 <script lang="ts">
-  import type { APIKeyResponseDto } from '@api';
+  import Icon from '$lib/components/elements/icon.svelte';
+  import type { ApiKeyResponseDto } from '@immich/sdk';
+  import { mdiKeyVariant } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import Button from '../elements/buttons/button.svelte';
   import FullScreenModal from '../shared-components/full-screen-modal.svelte';
-  import Icon from '$lib/components/elements/icon.svelte';
-  import { mdiKeyVariant } from '@mdi/js';
   import { NotificationType, notificationController } from '../shared-components/notification/notification';
 
-  export let apiKey: Partial<APIKeyResponseDto>;
+  export let apiKey: Partial<ApiKeyResponseDto>;
   export let title = 'API Key';
   export let cancelText = 'Cancel';
   export let submitText = 'Save';
@@ -15,7 +15,7 @@
 
   const dispatch = createEventDispatcher<{
     cancel: void;
-    submit: Partial<APIKeyResponseDto>;
+    submit: Partial<ApiKeyResponseDto>;
   }>();
   const handleCancel = () => dispatch('cancel');
   const handleSubmit = () => {
diff --git a/web/src/lib/components/forms/api-key-secret.svelte b/web/src/lib/components/forms/api-key-secret.svelte
index 7dcf39c36b..b5ed9550f6 100644
--- a/web/src/lib/components/forms/api-key-secret.svelte
+++ b/web/src/lib/components/forms/api-key-secret.svelte
@@ -1,10 +1,10 @@
 <script lang="ts">
+  import Icon from '$lib/components/elements/icon.svelte';
+  import { copyToClipboard } from '$lib/utils';
+  import { mdiKeyVariant } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
-  import { copyToClipboard } from '@api';
   import Button from '../elements/buttons/button.svelte';
   import FullScreenModal from '../shared-components/full-screen-modal.svelte';
-  import { mdiKeyVariant } from '@mdi/js';
-  import Icon from '$lib/components/elements/icon.svelte';
 
   export let secret = '';
 
diff --git a/web/src/lib/components/forms/library-import-paths-form.svelte b/web/src/lib/components/forms/library-import-paths-form.svelte
index bd32b39b5e..fddb4b9867 100644
--- a/web/src/lib/components/forms/library-import-paths-form.svelte
+++ b/web/src/lib/components/forms/library-import-paths-form.svelte
@@ -1,12 +1,11 @@
 <script lang="ts">
-  import { createEventDispatcher } from 'svelte';
-  import Button from '../elements/buttons/button.svelte';
-  import { handleError } from '../../utils/handle-error';
-  import LibraryImportPathForm from './library-import-path-form.svelte';
-  import { onMount } from 'svelte';
   import Icon from '$lib/components/elements/icon.svelte';
-  import type { LibraryResponseDto } from '@api';
+  import type { LibraryResponseDto } from '@immich/sdk';
   import { mdiPencilOutline } from '@mdi/js';
+  import { createEventDispatcher, onMount } from 'svelte';
+  import { handleError } from '../../utils/handle-error';
+  import Button from '../elements/buttons/button.svelte';
+  import LibraryImportPathForm from './library-import-path-form.svelte';
 
   export let library: Partial<LibraryResponseDto>;
 
diff --git a/web/src/lib/components/forms/library-rename-form.svelte b/web/src/lib/components/forms/library-rename-form.svelte
index 6d7d6865b1..1c83c53836 100644
--- a/web/src/lib/components/forms/library-rename-form.svelte
+++ b/web/src/lib/components/forms/library-rename-form.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
+  import type { LibraryResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import Button from '../elements/buttons/button.svelte';
-  import type { LibraryResponseDto } from '@api';
 
   export let library: Partial<LibraryResponseDto>;
 
diff --git a/web/src/lib/components/forms/library-scan-settings-form.svelte b/web/src/lib/components/forms/library-scan-settings-form.svelte
index 8a47fb65d7..f110a5a091 100644
--- a/web/src/lib/components/forms/library-scan-settings-form.svelte
+++ b/web/src/lib/components/forms/library-scan-settings-form.svelte
@@ -1,12 +1,11 @@
 <script lang="ts">
-  import { createEventDispatcher } from 'svelte';
-  import Button from '../elements/buttons/button.svelte';
-  import { LibraryType, type LibraryResponseDto } from '@api';
-  import { handleError } from '../../utils/handle-error';
-  import { onMount } from 'svelte';
   import Icon from '$lib/components/elements/icon.svelte';
-  import LibraryExclusionPatternForm from './library-exclusion-pattern-form.svelte';
+  import { LibraryType, type LibraryResponseDto } from '@immich/sdk';
   import { mdiPencilOutline } from '@mdi/js';
+  import { createEventDispatcher, onMount } from 'svelte';
+  import { handleError } from '../../utils/handle-error';
+  import Button from '../elements/buttons/button.svelte';
+  import LibraryExclusionPatternForm from './library-exclusion-pattern-form.svelte';
 
   export let library: Partial<LibraryResponseDto>;
 
diff --git a/web/src/lib/components/forms/login-form.svelte b/web/src/lib/components/forms/login-form.svelte
index 7bffbd9145..81ea0c1a19 100644
--- a/web/src/lib/components/forms/login-form.svelte
+++ b/web/src/lib/components/forms/login-form.svelte
@@ -3,8 +3,8 @@
   import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte';
   import { AppRoute } from '$lib/constants';
   import { featureFlags, serverConfig } from '$lib/stores/server-config.store';
+  import { oauth } from '$lib/utils';
   import { getServerErrorMessage, handleError } from '$lib/utils/handle-error';
-  import { oauth } from '@api';
   import { getServerConfig, login } from '@immich/sdk';
   import { createEventDispatcher, onMount } from 'svelte';
   import { fade } from 'svelte/transition';
diff --git a/web/src/lib/components/memory-page/memory-viewer.svelte b/web/src/lib/components/memory-page/memory-viewer.svelte
index c3e90941de..af26a7bffa 100644
--- a/web/src/lib/components/memory-page/memory-viewer.svelte
+++ b/web/src/lib/components/memory-page/memory-viewer.svelte
@@ -10,7 +10,7 @@
   import { memoryStore } from '$lib/stores/memory.store';
   import { getAssetThumbnailUrl } from '$lib/utils';
   import { fromLocalDateTime } from '$lib/utils/timeline-util';
-  import { getMemoryLane } from '@immich/sdk';
+  import { ThumbnailFormat, getMemoryLane } from '@immich/sdk';
   import { mdiChevronDown, mdiChevronLeft, mdiChevronRight, mdiChevronUp, mdiPause, mdiPlay } from '@mdi/js';
   import { DateTime } from 'luxon';
   import { onMount } from 'svelte';
@@ -168,7 +168,9 @@
           <button class="relative h-full w-full rounded-2xl" disabled={!previousMemory} on:click={toPreviousMemory}>
             <img
               class="h-full w-full rounded-2xl object-cover"
-              src={previousMemory ? getAssetThumbnailUrl(previousMemory.assets[0].id, 'JPEG') : noThumbnailUrl}
+              src={previousMemory
+                ? getAssetThumbnailUrl(previousMemory.assets[0].id, ThumbnailFormat.Jpeg)
+                : noThumbnailUrl}
               alt=""
               draggable="false"
             />
@@ -191,7 +193,7 @@
               <img
                 transition:fade
                 class="h-full w-full rounded-2xl object-contain transition-all"
-                src={getAssetThumbnailUrl(currentAsset.id, 'JPEG')}
+                src={getAssetThumbnailUrl(currentAsset.id, ThumbnailFormat.Jpeg)}
                 alt=""
                 draggable="false"
               />
@@ -231,7 +233,7 @@
           <button class="relative h-full w-full rounded-2xl" on:click={toNextMemory} disabled={!nextMemory}>
             <img
               class="h-full w-full rounded-2xl object-cover"
-              src={nextMemory ? getAssetThumbnailUrl(nextMemory.assets[0].id, 'JPEG') : noThumbnailUrl}
+              src={nextMemory ? getAssetThumbnailUrl(nextMemory.assets[0].id, ThumbnailFormat.Jpeg) : noThumbnailUrl}
               alt=""
               draggable="false"
             />
diff --git a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte
index 49fd685e95..786d65395a 100644
--- a/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte
+++ b/web/src/lib/components/onboarding-page/onboarding-storage-template.svelte
@@ -1,8 +1,7 @@
 <script lang="ts">
   import { featureFlags } from '$lib/stores/server-config.store';
   import { user } from '$lib/stores/user.store';
-  import { type SystemConfigDto } from '@api';
-  import { getConfig } from '@immich/sdk';
+  import { getConfig, type SystemConfigDto } from '@immich/sdk';
   import { mdiArrowLeft, mdiCheck } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import AdminSettings from '../admin-page/settings/admin-settings.svelte';
diff --git a/web/src/lib/components/photos-page/actions/add-to-album.svelte b/web/src/lib/components/photos-page/actions/add-to-album.svelte
index b34abac266..c7101922f4 100644
--- a/web/src/lib/components/photos-page/actions/add-to-album.svelte
+++ b/web/src/lib/components/photos-page/actions/add-to-album.svelte
@@ -8,8 +8,7 @@
   } from '$lib/components/shared-components/notification/notification';
   import { AppRoute } from '$lib/constants';
   import { addAssetsToAlbum } from '$lib/utils/asset-utils';
-  import { type AlbumResponseDto } from '@api';
-  import { createAlbum } from '@immich/sdk';
+  import { createAlbum, type AlbumResponseDto } from '@immich/sdk';
   import { getMenuContext } from '../asset-select-context-menu.svelte';
   import { getAssetControlContext } from '../asset-select-control-bar.svelte';
 
diff --git a/web/src/lib/components/photos-page/actions/asset-job-actions.svelte b/web/src/lib/components/photos-page/actions/asset-job-actions.svelte
index f4827a03ef..7b79cb36c0 100644
--- a/web/src/lib/components/photos-page/actions/asset-job-actions.svelte
+++ b/web/src/lib/components/photos-page/actions/asset-job-actions.svelte
@@ -6,8 +6,7 @@
   } from '$lib/components/shared-components/notification/notification';
   import { getAssetJobMessage, getAssetJobName } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { AssetJobName, AssetTypeEnum } from '@api';
-  import { runAssetJobs } from '@immich/sdk';
+  import { AssetJobName, AssetTypeEnum, runAssetJobs } from '@immich/sdk';
   import { getAssetControlContext } from '../asset-select-control-bar.svelte';
 
   export let jobs: AssetJobName[] = [
diff --git a/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte b/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
index d9290577cc..f870ac3d35 100644
--- a/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
+++ b/web/src/lib/components/photos-page/actions/remove-from-shared-link.svelte
@@ -2,8 +2,7 @@
   import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
   import { getKey } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { type SharedLinkResponseDto } from '@api';
-  import { removeSharedLinkAssets } from '@immich/sdk';
+  import { removeSharedLinkAssets, type SharedLinkResponseDto } from '@immich/sdk';
   import { mdiDeleteOutline } from '@mdi/js';
   import ConfirmDialogue from '../../shared-components/confirm-dialogue.svelte';
   import { NotificationType, notificationController } from '../../shared-components/notification/notification';
diff --git a/web/src/lib/components/photos-page/asset-date-group.svelte b/web/src/lib/components/photos-page/asset-date-group.svelte
index cf560dbbec..a38708e881 100644
--- a/web/src/lib/components/photos-page/asset-date-group.svelte
+++ b/web/src/lib/components/photos-page/asset-date-group.svelte
@@ -1,18 +1,17 @@
 <script lang="ts">
+  import Icon from '$lib/components/elements/icon.svelte';
+  import type { AssetInteractionStore } from '$lib/stores/asset-interaction.store';
+  import { assetViewingStore } from '$lib/stores/asset-viewing.store';
+  import type { AssetStore, Viewport } from '$lib/stores/assets.store';
   import { locale } from '$lib/stores/preferences.store';
   import { getAssetRatio } from '$lib/utils/asset-utils';
   import { formatGroupTitle, fromLocalDateTime, splitBucketIntoDateGroups } from '$lib/utils/timeline-util';
-  import type { AssetResponseDto } from '@api';
+  import type { AssetResponseDto } from '@immich/sdk';
+  import { mdiCheckCircle, mdiCircleOutline } from '@mdi/js';
   import justifiedLayout from 'justified-layout';
   import { createEventDispatcher } from 'svelte';
-  import Icon from '$lib/components/elements/icon.svelte';
   import { fly } from 'svelte/transition';
   import Thumbnail from '../assets/thumbnail/thumbnail.svelte';
-  import { assetViewingStore } from '$lib/stores/asset-viewing.store';
-  import type { AssetStore } from '$lib/stores/assets.store';
-  import type { AssetInteractionStore } from '$lib/stores/asset-interaction.store';
-  import type { Viewport } from '$lib/stores/assets.store';
-  import { mdiCheckCircle, mdiCircleOutline } from '@mdi/js';
 
   export let assets: AssetResponseDto[];
   export let bucketDate: string;
diff --git a/web/src/lib/components/photos-page/asset-grid.svelte b/web/src/lib/components/photos-page/asset-grid.svelte
index 059ce61ed3..a8eae24139 100644
--- a/web/src/lib/components/photos-page/asset-grid.svelte
+++ b/web/src/lib/components/photos-page/asset-grid.svelte
@@ -7,8 +7,11 @@
   import { BucketPosition, type AssetStore, type Viewport } from '$lib/stores/assets.store';
   import { locale, showDeleteModal } from '$lib/stores/preferences.store';
   import { isSearchEnabled } from '$lib/stores/search.store';
+  import { featureFlags } from '$lib/stores/server-config.store';
+  import { deleteAssets } from '$lib/utils/actions';
+  import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
   import { formatGroupTitle, splitBucketIntoDateGroups } from '$lib/utils/timeline-util';
-  import type { AlbumResponseDto, AssetResponseDto } from '@api';
+  import type { AlbumResponseDto, AssetResponseDto } from '@immich/sdk';
   import { DateTime } from 'luxon';
   import { createEventDispatcher, onDestroy, onMount } from 'svelte';
   import AssetViewer from '../asset-viewer/asset-viewer.svelte';
@@ -17,9 +20,6 @@
   import Scrollbar from '../shared-components/scrollbar/scrollbar.svelte';
   import ShowShortcuts from '../shared-components/show-shortcuts.svelte';
   import AssetDateGroup from './asset-date-group.svelte';
-  import { featureFlags } from '$lib/stores/server-config.store';
-  import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
-  import { deleteAssets } from '$lib/utils/actions';
   import DeleteAssetDialog from './delete-asset-dialog.svelte';
 
   export let isSelectionMode = false;
diff --git a/web/src/lib/components/photos-page/asset-select-control-bar.svelte b/web/src/lib/components/photos-page/asset-select-control-bar.svelte
index 8410f34aa9..a51be08f56 100644
--- a/web/src/lib/components/photos-page/asset-select-control-bar.svelte
+++ b/web/src/lib/components/photos-page/asset-select-control-bar.svelte
@@ -14,9 +14,9 @@
 
 <script lang="ts">
   import { locale } from '$lib/stores/preferences.store';
-  import type { AssetResponseDto } from '@api';
-  import ControlAppBar from '../shared-components/control-app-bar.svelte';
+  import type { AssetResponseDto } from '@immich/sdk';
   import { mdiClose } from '@mdi/js';
+  import ControlAppBar from '../shared-components/control-app-bar.svelte';
 
   export let assets: Set<AssetResponseDto>;
   export let clearSelect: () => void;
diff --git a/web/src/lib/components/photos-page/memory-lane.svelte b/web/src/lib/components/photos-page/memory-lane.svelte
index 751862109c..23d1beab51 100644
--- a/web/src/lib/components/photos-page/memory-lane.svelte
+++ b/web/src/lib/components/photos-page/memory-lane.svelte
@@ -4,7 +4,7 @@
   import { AppRoute, QueryParameter } from '$lib/constants';
   import { memoryStore } from '$lib/stores/memory.store';
   import { getAssetThumbnailUrl } from '$lib/utils';
-  import { getMemoryLane } from '@immich/sdk';
+  import { ThumbnailFormat, getMemoryLane } from '@immich/sdk';
   import { mdiChevronLeft, mdiChevronRight } from '@mdi/js';
   import { onMount } from 'svelte';
   import { fade } from 'svelte/transition';
@@ -73,7 +73,7 @@
         >
           <img
             class="h-full w-full rounded-xl object-cover"
-            src={getAssetThumbnailUrl(memory.assets[0].id, 'JPEG')}
+            src={getAssetThumbnailUrl(memory.assets[0].id, ThumbnailFormat.Jpeg)}
             alt={memory.title}
             draggable="false"
           />
diff --git a/web/src/lib/components/share-page/individual-shared-viewer.svelte b/web/src/lib/components/share-page/individual-shared-viewer.svelte
index 9c5ed2ea26..37b2983ae1 100644
--- a/web/src/lib/components/share-page/individual-shared-viewer.svelte
+++ b/web/src/lib/components/share-page/individual-shared-viewer.svelte
@@ -6,8 +6,7 @@
   import { downloadArchive } from '$lib/utils/asset-utils';
   import { fileUploadHandler, openFileUploadDialog } from '$lib/utils/file-uploader';
   import { handleError } from '$lib/utils/handle-error';
-  import { type AssetResponseDto, type SharedLinkResponseDto } from '@api';
-  import { addSharedLinkAssets } from '@immich/sdk';
+  import { addSharedLinkAssets, type AssetResponseDto, type SharedLinkResponseDto } from '@immich/sdk';
   import { mdiArrowLeft, mdiFileImagePlusOutline, mdiFolderDownloadOutline, mdiSelectAll } from '@mdi/js';
   import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
   import DownloadAction from '../photos-page/actions/download-action.svelte';
diff --git a/web/src/lib/components/shared-components/album-selection-modal.svelte b/web/src/lib/components/shared-components/album-selection-modal.svelte
index 6d85ea0d47..6b3ebc1bb9 100644
--- a/web/src/lib/components/shared-components/album-selection-modal.svelte
+++ b/web/src/lib/components/shared-components/album-selection-modal.svelte
@@ -1,7 +1,6 @@
 <script lang="ts">
   import Icon from '$lib/components/elements/icon.svelte';
-  import { type AlbumResponseDto } from '@api';
-  import { getAllAlbums } from '@immich/sdk';
+  import { getAllAlbums, type AlbumResponseDto } from '@immich/sdk';
   import { mdiPlus } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import AlbumListItem from '../asset-viewer/album-list-item.svelte';
diff --git a/web/src/lib/components/shared-components/change-location.svelte b/web/src/lib/components/shared-components/change-location.svelte
index 2186986c56..a8fbe3a020 100644
--- a/web/src/lib/components/shared-components/change-location.svelte
+++ b/web/src/lib/components/shared-components/change-location.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { AssetResponseDto } from '@api';
+  import type { AssetResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import ConfirmDialogue from './confirm-dialogue.svelte';
   import Map from './map/map.svelte';
diff --git a/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte b/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
index 7eb2fce7d7..28a11999ab 100644
--- a/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
+++ b/web/src/lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte
@@ -6,9 +6,9 @@
   import Button from '$lib/components/elements/buttons/button.svelte';
   import Icon from '$lib/components/elements/icon.svelte';
   import { serverConfig } from '$lib/stores/server-config.store';
+  import { copyToClipboard, makeSharedLinkUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { SharedLinkType, copyToClipboard, makeSharedLinkUrl, type SharedLinkResponseDto } from '@api';
-  import { createSharedLink, updateSharedLink } from '@immich/sdk';
+  import { SharedLinkType, createSharedLink, updateSharedLink, type SharedLinkResponseDto } from '@immich/sdk';
   import { mdiLink } from '@mdi/js';
   import { createEventDispatcher, onMount } from 'svelte';
   import BaseModal from '../base-modal.svelte';
diff --git a/web/src/lib/components/shared-components/gallery-viewer/asset-selection-viewer.svelte b/web/src/lib/components/shared-components/gallery-viewer/asset-selection-viewer.svelte
index 1b2f80da80..491b36f8b9 100644
--- a/web/src/lib/components/shared-components/gallery-viewer/asset-selection-viewer.svelte
+++ b/web/src/lib/components/shared-components/gallery-viewer/asset-selection-viewer.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
   import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
   import { getThumbnailSize } from '$lib/utils/thumbnail-util';
-  import { type AssetResponseDto, ThumbnailFormat } from '@api';
+  import { ThumbnailFormat, type AssetResponseDto } from '@immich/sdk';
   import { createEventDispatcher } from 'svelte';
   import { flip } from 'svelte/animate';
 
diff --git a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte
index a3bc54c454..fa1d7d6732 100644
--- a/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte
+++ b/web/src/lib/components/shared-components/gallery-viewer/gallery-viewer.svelte
@@ -1,15 +1,14 @@
 <script lang="ts">
   import { page } from '$app/stores';
   import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
-  import { handleError } from '$lib/utils/handle-error';
-  import { type AssetResponseDto, ThumbnailFormat } from '@api';
-  import AssetViewer from '../../asset-viewer/asset-viewer.svelte';
-  import { flip } from 'svelte/animate';
-  import { getThumbnailSize } from '$lib/utils/thumbnail-util';
   import { assetViewingStore } from '$lib/stores/asset-viewing.store';
-  import { onDestroy } from 'svelte';
-  import { createEventDispatcher } from 'svelte';
   import type { BucketPosition } from '$lib/stores/assets.store';
+  import { handleError } from '$lib/utils/handle-error';
+  import { getThumbnailSize } from '$lib/utils/thumbnail-util';
+  import { ThumbnailFormat, type AssetResponseDto } from '@immich/sdk';
+  import { createEventDispatcher, onDestroy } from 'svelte';
+  import { flip } from 'svelte/animate';
+  import AssetViewer from '../../asset-viewer/asset-viewer.svelte';
 
   const dispatch = createEventDispatcher<{ intersected: { container: HTMLDivElement; position: BucketPosition } }>();
 
diff --git a/web/src/lib/components/shared-components/map/map.svelte b/web/src/lib/components/shared-components/map/map.svelte
index ac0f0351cf..0d43f97aef 100644
--- a/web/src/lib/components/shared-components/map/map.svelte
+++ b/web/src/lib/components/shared-components/map/map.svelte
@@ -3,7 +3,7 @@
   import { Theme } from '$lib/constants';
   import { colorTheme, mapSettings } from '$lib/stores/preferences.store';
   import { getAssetThumbnailUrl } from '$lib/utils';
-  import { getMapStyle, type MapMarkerResponseDto } from '@immich/sdk';
+  import { getMapStyle, MapTheme, type MapMarkerResponseDto } from '@immich/sdk';
   import { mdiCog, mdiMapMarker } from '@mdi/js';
   import type { Feature, GeoJsonProperties, Geometry, Point } from 'geojson';
   import type { GeoJSONSource, LngLatLike, StyleSpecification } from 'maplibre-gl';
@@ -38,7 +38,7 @@
 
   $: style = (() =>
     getMapStyle({
-      theme: $mapSettings.allowDarkMode ? $colorTheme.value : Theme.LIGHT,
+      theme: ($mapSettings.allowDarkMode ? $colorTheme.value : Theme.LIGHT) as unknown as MapTheme,
     }) as Promise<StyleSpecification>)();
 
   const dispatch = createEventDispatcher<{
diff --git a/web/src/lib/components/shared-components/navigation-bar/account-info-panel.svelte b/web/src/lib/components/shared-components/navigation-bar/account-info-panel.svelte
index e6d034f4fc..4087f37bd1 100644
--- a/web/src/lib/components/shared-components/navigation-bar/account-info-panel.svelte
+++ b/web/src/lib/components/shared-components/navigation-bar/account-info-panel.svelte
@@ -8,7 +8,7 @@
   import { mdiCog, mdiLogout, mdiPencil } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
   import { fade } from 'svelte/transition';
-  import { NotificationType, notificationController } from '../notification/notification';
+  import { notificationController, NotificationType } from '../notification/notification';
   import UserAvatar from '../user-avatar.svelte';
   import AvatarSelector from './avatar-selector.svelte';
 
diff --git a/web/src/lib/components/shared-components/navigation-bar/avatar-selector.svelte b/web/src/lib/components/shared-components/navigation-bar/avatar-selector.svelte
index 6b9e74a9b2..3ba5745ae2 100644
--- a/web/src/lib/components/shared-components/navigation-bar/avatar-selector.svelte
+++ b/web/src/lib/components/shared-components/navigation-bar/avatar-selector.svelte
@@ -1,8 +1,8 @@
 <script lang="ts">
+  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
+  import { UserAvatarColor, type UserResponseDto } from '@immich/sdk';
   import { mdiClose } from '@mdi/js';
   import { createEventDispatcher } from 'svelte';
-  import { UserAvatarColor, type UserResponseDto } from '@api';
-  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
   import FullScreenModal from '../full-screen-modal.svelte';
   import UserAvatar from '../user-avatar.svelte';
 
diff --git a/web/src/lib/components/shared-components/profile-image-cropper.svelte b/web/src/lib/components/shared-components/profile-image-cropper.svelte
index 54f06d2854..d4d60e836a 100644
--- a/web/src/lib/components/shared-components/profile-image-cropper.svelte
+++ b/web/src/lib/components/shared-components/profile-image-cropper.svelte
@@ -1,8 +1,7 @@
 <script lang="ts">
   import { user } from '$lib/stores/user.store';
   import { handleError } from '$lib/utils/handle-error';
-  import { type AssetResponseDto } from '@api';
-  import { createProfileImage } from '@immich/sdk';
+  import { createProfileImage, type AssetResponseDto } from '@immich/sdk';
   import domtoimage from 'dom-to-image';
   import { createEventDispatcher, onMount } from 'svelte';
   import PhotoViewer from '../asset-viewer/photo-viewer.svelte';
diff --git a/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte
index 5fcc3db450..ffc78e59fb 100644
--- a/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte
+++ b/web/src/lib/components/shared-components/search-bar/search-filter-box.svelte
@@ -4,7 +4,7 @@
   import Icon from '$lib/components/elements/icon.svelte';
   import { getPeopleThumbnailUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { SearchSuggestionType, type PersonResponseDto } from '@api';
+  import { SearchSuggestionType, type PersonResponseDto } from '@immich/sdk';
   import { getAllPeople, getSearchSuggestions } from '@immich/sdk';
   import { mdiArrowRight, mdiClose } from '@mdi/js';
   import { onMount } from 'svelte';
diff --git a/web/src/lib/components/shared-components/side-bar/side-bar.svelte b/web/src/lib/components/shared-components/side-bar/side-bar.svelte
index e1eafb192d..cb59511ffa 100644
--- a/web/src/lib/components/shared-components/side-bar/side-bar.svelte
+++ b/web/src/lib/components/shared-components/side-bar/side-bar.svelte
@@ -2,7 +2,6 @@
   import { page } from '$app/stores';
   import { locale, sidebarSettings } from '$lib/stores/preferences.store';
   import { featureFlags } from '$lib/stores/server-config.store';
-  import { type AssetApiGetAssetStatisticsRequest } from '@api';
   import { getAlbumCount, getAssetStatistics } from '@immich/sdk';
   import {
     mdiAccount,
@@ -24,7 +23,7 @@
   import SideBarButton from './side-bar-button.svelte';
   import SideBarSection from './side-bar-section.svelte';
 
-  const getStats = (dto: AssetApiGetAssetStatisticsRequest) => getAssetStatistics(dto);
+  const getStats = (dto: Parameters<typeof getAssetStatistics>[0]) => getAssetStatistics(dto);
 
   const handleAlbumCount = async () => {
     try {
diff --git a/web/src/lib/components/shared-components/version-announcement-box.svelte b/web/src/lib/components/shared-components/version-announcement-box.svelte
index d0415f54ba..93ba1d7a4b 100644
--- a/web/src/lib/components/shared-components/version-announcement-box.svelte
+++ b/web/src/lib/components/shared-components/version-announcement-box.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
-  import type { ServerVersionResponseDto } from '@api';
   import { websocketStore } from '$lib/stores/websocket';
+  import type { ServerVersionResponseDto } from '@immich/sdk';
   import Button from '../elements/buttons/button.svelte';
   import FullScreenModal from './full-screen-modal.svelte';
 
diff --git a/web/src/lib/components/sharedlinks-page/shared-link-card.svelte b/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
index 14da866229..207a15bfc9 100644
--- a/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
+++ b/web/src/lib/components/sharedlinks-page/shared-link-card.svelte
@@ -4,8 +4,13 @@
   import Icon from '$lib/components/elements/icon.svelte';
   import { AppRoute } from '$lib/constants';
   import { getAssetThumbnailUrl } from '$lib/utils';
-  import { SharedLinkType, ThumbnailFormat, type AssetResponseDto, type SharedLinkResponseDto } from '@api';
-  import { getAssetInfo } from '@immich/sdk';
+  import {
+    SharedLinkType,
+    ThumbnailFormat,
+    getAssetInfo,
+    type AssetResponseDto,
+    type SharedLinkResponseDto,
+  } from '@immich/sdk';
   import { mdiCircleEditOutline, mdiContentCopy, mdiDelete, mdiOpenInNew } from '@mdi/js';
   import * as luxon from 'luxon';
   import { createEventDispatcher } from 'svelte';
diff --git a/web/src/lib/components/user-settings-page/change-password-settings.svelte b/web/src/lib/components/user-settings-page/change-password-settings.svelte
index c90eaef833..42d9107488 100644
--- a/web/src/lib/components/user-settings-page/change-password-settings.svelte
+++ b/web/src/lib/components/user-settings-page/change-password-settings.svelte
@@ -3,7 +3,7 @@
     notificationController,
     NotificationType,
   } from '$lib/components/shared-components/notification/notification';
-  import { type ApiError } from '@api';
+  import { type ApiError } from '$lib/utils';
   import { changePassword } from '@immich/sdk';
   import { fade } from 'svelte/transition';
   import SettingInputField, { SettingInputFieldType } from '../admin-page/settings/setting-input-field.svelte';
diff --git a/web/src/lib/components/user-settings-page/device-card.svelte b/web/src/lib/components/user-settings-page/device-card.svelte
index cb6f39e798..29067aaca1 100644
--- a/web/src/lib/components/user-settings-page/device-card.svelte
+++ b/web/src/lib/components/user-settings-page/device-card.svelte
@@ -1,19 +1,19 @@
 <script lang="ts">
-  import { locale } from '$lib/stores/preferences.store';
-  import type { AuthDeviceResponseDto } from '@api';
-  import { DateTime, type ToRelativeCalendarOptions } from 'luxon';
-  import { createEventDispatcher } from 'svelte';
   import Icon from '$lib/components/elements/icon.svelte';
+  import { locale } from '$lib/stores/preferences.store';
+  import type { AuthDeviceResponseDto } from '@immich/sdk';
   import {
     mdiAndroid,
     mdiApple,
     mdiAppleSafari,
-    mdiMicrosoftWindows,
-    mdiLinux,
     mdiGoogleChrome,
-    mdiTrashCanOutline,
     mdiHelp,
+    mdiLinux,
+    mdiMicrosoftWindows,
+    mdiTrashCanOutline,
   } from '@mdi/js';
+  import { DateTime, type ToRelativeCalendarOptions } from 'luxon';
+  import { createEventDispatcher } from 'svelte';
 
   export let device: AuthDeviceResponseDto;
 
diff --git a/web/src/lib/components/user-settings-page/device-list.svelte b/web/src/lib/components/user-settings-page/device-list.svelte
index a933c12d67..080e79145d 100644
--- a/web/src/lib/components/user-settings-page/device-list.svelte
+++ b/web/src/lib/components/user-settings-page/device-list.svelte
@@ -1,10 +1,9 @@
 <script lang="ts">
-  import { type AuthDeviceResponseDto } from '@api';
-  import { getAuthDevices, logoutAuthDevice, logoutAuthDevices } from '@immich/sdk';
+  import { getAuthDevices, logoutAuthDevice, logoutAuthDevices, type AuthDeviceResponseDto } from '@immich/sdk';
   import { handleError } from '../../utils/handle-error';
   import Button from '../elements/buttons/button.svelte';
   import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
-  import { notificationController, NotificationType } from '../shared-components/notification/notification';
+  import { NotificationType, notificationController } from '../shared-components/notification/notification';
   import DeviceCard from './device-card.svelte';
 
   export let devices: AuthDeviceResponseDto[];
diff --git a/web/src/lib/components/user-settings-page/library-list.svelte b/web/src/lib/components/user-settings-page/library-list.svelte
index deac035336..256a3c6f99 100644
--- a/web/src/lib/components/user-settings-page/library-list.svelte
+++ b/web/src/lib/components/user-settings-page/library-list.svelte
@@ -4,8 +4,8 @@
   import { getBytesWithUnit } from '$lib/utils/byte-units';
   import { getContextMenuPosition } from '$lib/utils/context-menu';
   import { handleError } from '$lib/utils/handle-error';
-  import { LibraryType, type LibraryResponseDto, type LibraryStatsResponseDto } from '@api';
   import {
+    LibraryType,
     createLibrary,
     deleteLibrary,
     getLibraries,
@@ -13,6 +13,8 @@
     removeOfflineFiles,
     scanLibrary,
     updateLibrary,
+    type LibraryResponseDto,
+    type LibraryStatsResponseDto,
   } from '@immich/sdk';
   import { mdiDatabase, mdiDotsVertical, mdiUpload } from '@mdi/js';
   import { onMount } from 'svelte';
diff --git a/web/src/lib/components/user-settings-page/memories-settings.svelte b/web/src/lib/components/user-settings-page/memories-settings.svelte
index 4a93a5810c..8dc34f5374 100644
--- a/web/src/lib/components/user-settings-page/memories-settings.svelte
+++ b/web/src/lib/components/user-settings-page/memories-settings.svelte
@@ -3,8 +3,7 @@
     notificationController,
     NotificationType,
   } from '$lib/components/shared-components/notification/notification';
-  import { type UserResponseDto } from '@api';
-  import { updateUser } from '@immich/sdk';
+  import { updateUser, type UserResponseDto } from '@immich/sdk';
   import { fade } from 'svelte/transition';
   import { handleError } from '../../utils/handle-error';
   import SettingSwitch from '../admin-page/settings/setting-switch.svelte';
diff --git a/web/src/lib/components/user-settings-page/oauth-settings.svelte b/web/src/lib/components/user-settings-page/oauth-settings.svelte
index 6e529b351a..4ac27190bb 100644
--- a/web/src/lib/components/user-settings-page/oauth-settings.svelte
+++ b/web/src/lib/components/user-settings-page/oauth-settings.svelte
@@ -1,7 +1,8 @@
 <script lang="ts">
   import { goto } from '$app/navigation';
   import { featureFlags } from '$lib/stores/server-config.store';
-  import { oauth, type UserResponseDto } from '@api';
+  import { oauth } from '$lib/utils';
+  import { type UserResponseDto } from '@immich/sdk';
   import { onMount } from 'svelte';
   import { fade } from 'svelte/transition';
   import { handleError } from '../../utils/handle-error';
diff --git a/web/src/lib/components/user-settings-page/partner-selection-modal.svelte b/web/src/lib/components/user-settings-page/partner-selection-modal.svelte
index 6ba5da8c2a..6d920d3103 100644
--- a/web/src/lib/components/user-settings-page/partner-selection-modal.svelte
+++ b/web/src/lib/components/user-settings-page/partner-selection-modal.svelte
@@ -1,6 +1,5 @@
 <script lang="ts">
-  import { type UserResponseDto } from '@api';
-  import { getAllUsers, getPartners } from '@immich/sdk';
+  import { getAllUsers, getPartners, type UserResponseDto } from '@immich/sdk';
   import { createEventDispatcher, onMount } from 'svelte';
   import Button from '../elements/buttons/button.svelte';
   import BaseModal from '../shared-components/base-modal.svelte';
diff --git a/web/src/lib/components/user-settings-page/partner-settings.svelte b/web/src/lib/components/user-settings-page/partner-settings.svelte
index 5cf55230ff..a485564191 100644
--- a/web/src/lib/components/user-settings-page/partner-settings.svelte
+++ b/web/src/lib/components/user-settings-page/partner-settings.svelte
@@ -1,6 +1,12 @@
 <script lang="ts">
-  import { type PartnerResponseDto, type UserResponseDto } from '@api';
-  import { createPartner, getPartners, removePartner, updatePartner } from '@immich/sdk';
+  import {
+    createPartner,
+    getPartners,
+    removePartner,
+    updatePartner,
+    type PartnerResponseDto,
+    type UserResponseDto,
+  } from '@immich/sdk';
   import { mdiCheck, mdiClose } from '@mdi/js';
   import { onMount } from 'svelte';
   import { handleError } from '../../utils/handle-error';
diff --git a/web/src/lib/components/user-settings-page/user-api-key-list.svelte b/web/src/lib/components/user-settings-page/user-api-key-list.svelte
index 72aa06f314..9eca630bf6 100644
--- a/web/src/lib/components/user-settings-page/user-api-key-list.svelte
+++ b/web/src/lib/components/user-settings-page/user-api-key-list.svelte
@@ -1,8 +1,7 @@
 <script lang="ts">
   import Icon from '$lib/components/elements/icon.svelte';
   import { locale } from '$lib/stores/preferences.store';
-  import { type APIKeyResponseDto } from '@api';
-  import { createApiKey, deleteApiKey, getApiKeys, updateApiKey } from '@immich/sdk';
+  import { createApiKey, deleteApiKey, getApiKeys, updateApiKey, type ApiKeyResponseDto } from '@immich/sdk';
   import { mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
   import { fade } from 'svelte/transition';
   import { handleError } from '../../utils/handle-error';
@@ -12,11 +11,11 @@
   import ConfirmDialogue from '../shared-components/confirm-dialogue.svelte';
   import { NotificationType, notificationController } from '../shared-components/notification/notification';
 
-  export let keys: APIKeyResponseDto[];
+  export let keys: ApiKeyResponseDto[];
 
-  let newKey: Partial<APIKeyResponseDto> | null = null;
-  let editKey: APIKeyResponseDto | null = null;
-  let deleteKey: APIKeyResponseDto | null = null;
+  let newKey: Partial<ApiKeyResponseDto> | null = null;
+  let editKey: ApiKeyResponseDto | null = null;
+  let deleteKey: ApiKeyResponseDto | null = null;
   let secret = '';
 
   const format: Intl.DateTimeFormatOptions = {
@@ -29,7 +28,7 @@
     keys = await getApiKeys();
   }
 
-  const handleCreate = async (detail: Partial<APIKeyResponseDto>) => {
+  const handleCreate = async (detail: Partial<ApiKeyResponseDto>) => {
     try {
       const data = await createApiKey({ apiKeyCreateDto: detail });
       secret = data.secret;
@@ -41,7 +40,7 @@
     }
   };
 
-  const handleUpdate = async (detail: Partial<APIKeyResponseDto>) => {
+  const handleUpdate = async (detail: Partial<ApiKeyResponseDto>) => {
     if (!editKey || !detail.name) {
       return;
     }
diff --git a/web/src/lib/components/user-settings-page/user-settings-list.svelte b/web/src/lib/components/user-settings-page/user-settings-list.svelte
index 77e9fac69d..56177cfb0b 100644
--- a/web/src/lib/components/user-settings-page/user-settings-list.svelte
+++ b/web/src/lib/components/user-settings-page/user-settings-list.svelte
@@ -1,25 +1,26 @@
 <script lang="ts">
   import { browser } from '$app/environment';
   import { page } from '$app/stores';
+  import { OpenSettingQueryParameterValue, QueryParameter } from '$lib/constants';
   import { featureFlags } from '$lib/stores/server-config.store';
-  import { type APIKeyResponseDto, type AuthDeviceResponseDto, oauth } from '@api';
+  import { user } from '$lib/stores/user.store';
+  import { oauth } from '$lib/utils';
+  import { type ApiKeyResponseDto, type AuthDeviceResponseDto } from '@immich/sdk';
   import SettingAccordion from '../admin-page/settings/setting-accordion.svelte';
+  import AppearanceSettings from './appearance-settings.svelte';
   import ChangePasswordSettings from './change-password-settings.svelte';
   import DeviceList from './device-list.svelte';
   import LibraryList from './library-list.svelte';
   import MemoriesSettings from './memories-settings.svelte';
   import OAuthSettings from './oauth-settings.svelte';
   import PartnerSettings from './partner-settings.svelte';
+  import QualitySettings from './quality-settings.svelte';
   import SidebarSettings from './sidebar-settings.svelte';
+  import TrashSettings from './trash-settings.svelte';
   import UserAPIKeyList from './user-api-key-list.svelte';
   import UserProfileSettings from './user-profile-settings.svelte';
-  import { user } from '$lib/stores/user.store';
-  import { OpenSettingQueryParameterValue, QueryParameter } from '$lib/constants';
-  import AppearanceSettings from './appearance-settings.svelte';
-  import TrashSettings from './trash-settings.svelte';
-  import QualitySettings from './quality-settings.svelte';
 
-  export let keys: APIKeyResponseDto[] = [];
+  export let keys: ApiKeyResponseDto[] = [];
   export let devices: AuthDeviceResponseDto[] = [];
 
   let oauthOpen = false;
diff --git a/web/src/lib/stores/asset-interaction.store.ts b/web/src/lib/stores/asset-interaction.store.ts
index 8b36861579..b02847afd1 100644
--- a/web/src/lib/stores/asset-interaction.store.ts
+++ b/web/src/lib/stores/asset-interaction.store.ts
@@ -1,4 +1,4 @@
-import type { AssetResponseDto } from '@api';
+import type { AssetResponseDto } from '@immich/sdk';
 import { derived, writable } from 'svelte/store';
 
 export interface AssetInteractionStore {
diff --git a/web/src/lib/stores/asset-viewing.store.ts b/web/src/lib/stores/asset-viewing.store.ts
index 13169b8543..f9ddbd76e8 100644
--- a/web/src/lib/stores/asset-viewing.store.ts
+++ b/web/src/lib/stores/asset-viewing.store.ts
@@ -1,6 +1,5 @@
 import { getKey } from '$lib/utils';
-import { type AssetResponseDto } from '@api';
-import { getAssetInfo } from '@immich/sdk';
+import { getAssetInfo, type AssetResponseDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
 
 function createAssetViewingStore() {
diff --git a/web/src/lib/stores/assets.store.ts b/web/src/lib/stores/assets.store.ts
index e42a8ff982..7dbe5d6b2d 100644
--- a/web/src/lib/stores/assets.store.ts
+++ b/web/src/lib/stores/assets.store.ts
@@ -1,6 +1,5 @@
 import { getKey } from '$lib/utils';
-import { getTimeBucket, getTimeBuckets, type AssetResponseDto } from '@immich/sdk';
-import { TimeBucketSize, type AssetApiGetTimeBucketsRequest } from '@immich/sdk/axios';
+import { TimeBucketSize, getTimeBucket, getTimeBuckets, type AssetResponseDto } from '@immich/sdk';
 import { throttle } from 'lodash-es';
 import { DateTime } from 'luxon';
 import { writable, type Unsubscriber } from 'svelte/store';
@@ -13,7 +12,7 @@ export enum BucketPosition {
   Visible = 'visible',
   Unknown = 'unknown',
 }
-
+type AssetApiGetTimeBucketsRequest = Parameters<typeof getTimeBuckets>[0];
 export type AssetStoreOptions = Omit<AssetApiGetTimeBucketsRequest, 'size'>;
 
 export interface Viewport {
@@ -157,10 +156,7 @@ export class AssetStore {
     this.assetToBucket = {};
     this.albumAssets = new Set();
 
-    const buckets = await getTimeBuckets({
-      ...this.options,
-      key: getKey(),
-    });
+    const buckets = await getTimeBuckets({ ...this.options, key: getKey() });
 
     this.initialized = true;
 
diff --git a/web/src/lib/stores/memory.store.ts b/web/src/lib/stores/memory.store.ts
index 23456431e5..b157c41584 100644
--- a/web/src/lib/stores/memory.store.ts
+++ b/web/src/lib/stores/memory.store.ts
@@ -1,4 +1,4 @@
+import type { MemoryLaneResponseDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
-import type { MemoryLaneResponseDto } from '@api';
 
 export const memoryStore = writable<MemoryLaneResponseDto[]>();
diff --git a/web/src/lib/stores/server-config.store.ts b/web/src/lib/stores/server-config.store.ts
index 9c48f4faf2..5b0a529834 100644
--- a/web/src/lib/stores/server-config.store.ts
+++ b/web/src/lib/stores/server-config.store.ts
@@ -1,5 +1,4 @@
-import { type ServerConfigDto, type ServerFeaturesDto } from '@api';
-import { getServerConfig, getServerFeatures } from '@immich/sdk';
+import { getServerConfig, getServerFeatures, type ServerConfigDto, type ServerFeaturesDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
 
 export type FeatureFlags = ServerFeaturesDto & { loaded: boolean };
diff --git a/web/src/lib/stores/server-info.store.ts b/web/src/lib/stores/server-info.store.ts
index fce522c143..817bbeca4a 100644
--- a/web/src/lib/stores/server-info.store.ts
+++ b/web/src/lib/stores/server-info.store.ts
@@ -1,4 +1,4 @@
+import type { ServerInfoResponseDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
-import type { ServerInfoResponseDto } from '@api';
 
 export const serverInfo = writable<ServerInfoResponseDto>();
diff --git a/web/src/lib/stores/stacked-asset.store.ts b/web/src/lib/stores/stacked-asset.store.ts
index 85a0f571ed..09234641ad 100644
--- a/web/src/lib/stores/stacked-asset.store.ts
+++ b/web/src/lib/stores/stacked-asset.store.ts
@@ -1,4 +1,4 @@
+import type { AssetResponseDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
-import type { AssetResponseDto } from '@api';
 
 export const stackAssetsStore = writable<AssetResponseDto[]>([]);
diff --git a/web/src/lib/stores/user.store.ts b/web/src/lib/stores/user.store.ts
index 7f737e9fcc..66091ff52d 100644
--- a/web/src/lib/stores/user.store.ts
+++ b/web/src/lib/stores/user.store.ts
@@ -1,5 +1,5 @@
+import type { UserResponseDto } from '@immich/sdk';
 import { writable } from 'svelte/store';
-import type { UserResponseDto } from '@api';
 
 export let user = writable<UserResponseDto>();
 
diff --git a/web/src/lib/stores/websocket.ts b/web/src/lib/stores/websocket.ts
index 5b59e2c823..71ba4354f0 100644
--- a/web/src/lib/stores/websocket.ts
+++ b/web/src/lib/stores/websocket.ts
@@ -1,5 +1,5 @@
-import type { AssetResponseDto, ServerVersionResponseDto } from '@api';
-import { type Socket, io } from 'socket.io-client';
+import type { AssetResponseDto, ServerVersionResponseDto } from '@immich/sdk';
+import { io, type Socket } from 'socket.io-client';
 import { get, writable } from 'svelte/store';
 import { loadConfig } from './server-config.store';
 import { user } from './user.store';
diff --git a/web/src/lib/utils.ts b/web/src/lib/utils.ts
index 13b0a2e735..c879fd90a5 100644
--- a/web/src/lib/utils.ts
+++ b/web/src/lib/utils.ts
@@ -1,7 +1,20 @@
 import { goto } from '$app/navigation';
 import { page } from '$app/stores';
-import { defaults } from '@immich/sdk';
-import { AssetJobName, JobName, ThumbnailFormat, common } from '@immich/sdk/axios';
+import { NotificationType, notificationController } from '$lib/components/shared-components/notification/notification';
+import { handleError } from '$lib/utils/handle-error';
+import {
+  AssetJobName,
+  JobName,
+  ThumbnailFormat,
+  defaults,
+  finishOAuth,
+  linkOAuthAccount,
+  startOAuth,
+  unlinkOAuthAccount,
+  type UserResponseDto,
+} from '@immich/sdk';
+import { common } from '@immich/sdk/axios';
+import type { AxiosError } from 'axios';
 import { get } from 'svelte/store';
 
 interface UpdateParamAction {
@@ -121,3 +134,58 @@ export const getAssetJobMessage = (job: AssetJobName) => {
 
   return messages[job];
 };
+
+export type ApiError = AxiosError<{ message: string }>;
+
+export const copyToClipboard = async (secret: string) => {
+  try {
+    await navigator.clipboard.writeText(secret);
+    notificationController.show({ message: 'Copied to clipboard!', type: NotificationType.Info });
+  } catch (error) {
+    handleError(error, 'Cannot copy to clipboard, make sure you are accessing the page through https');
+  }
+};
+
+export const makeSharedLinkUrl = (externalDomain: string, key: string) => {
+  let url = externalDomain || window.location.origin;
+  if (!url.endsWith('/')) {
+    url += '/';
+  }
+  return `${url}share/${key}`;
+};
+
+export const oauth = {
+  isCallback: (location: Location) => {
+    const search = location.search;
+    return search.includes('code=') || search.includes('error=');
+  },
+  isAutoLaunchDisabled: (location: Location) => {
+    const values = ['autoLaunch=0', 'password=1', 'password=true'];
+    for (const value of values) {
+      if (location.search.includes(value)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  authorize: async (location: Location) => {
+    try {
+      const redirectUri = location.href.split('?')[0];
+      const { url } = await startOAuth({ oAuthConfigDto: { redirectUri } });
+      window.location.href = url;
+      return true;
+    } catch (error) {
+      handleError(error, 'Unable to login with OAuth');
+      return false;
+    }
+  },
+  login: (location: Location) => {
+    return finishOAuth({ oAuthCallbackDto: { url: location.href } });
+  },
+  link: (location: Location): Promise<UserResponseDto> => {
+    return linkOAuthAccount({ oAuthCallbackDto: { url: location.href } });
+  },
+  unlink: () => {
+    return unlinkOAuthAccount();
+  },
+};
diff --git a/web/src/lib/utils/asset-utils.spec.ts b/web/src/lib/utils/asset-utils.spec.ts
index 8f753ca625..8970a6a652 100644
--- a/web/src/lib/utils/asset-utils.spec.ts
+++ b/web/src/lib/utils/asset-utils.spec.ts
@@ -1,4 +1,4 @@
-import type { AssetResponseDto } from '@api';
+import type { AssetResponseDto } from '@immich/sdk';
 import { getAssetFilename, getFilenameExtension } from './asset-utils';
 
 describe('get file extension from filename', () => {
diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts
index f858cf191a..6120bbcfcc 100644
--- a/web/src/lib/utils/asset-utils.ts
+++ b/web/src/lib/utils/asset-utils.ts
@@ -1,6 +1,6 @@
+import { api } from '$lib/api';
 import { notificationController, NotificationType } from '$lib/components/shared-components/notification/notification';
 import { downloadManager } from '$lib/stores/download';
-import { api } from '@api';
 import {
   addAssetsToAlbum as addAssets,
   getDownloadInfo,
diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts
index 3da82cd428..929c1ee550 100644
--- a/web/src/lib/utils/file-uploader.ts
+++ b/web/src/lib/utils/file-uploader.ts
@@ -1,10 +1,10 @@
+import { api } from '$lib/api';
 import { UploadState } from '$lib/models/upload-asset';
 import { uploadAssetsStore } from '$lib/stores/upload';
 import { getKey } from '$lib/utils';
 import { addAssetsToAlbum } from '$lib/utils/asset-utils';
 import { ExecutorQueue } from '$lib/utils/executor-queue';
-import { api, type AssetFileUploadResponseDto } from '@api';
-import { getSupportedMediaTypes } from '@immich/sdk';
+import { getSupportedMediaTypes, type AssetFileUploadResponseDto } from '@immich/sdk';
 import { getServerErrorMessage, handleError } from './handle-error';
 
 let _extensions: string[];
diff --git a/web/src/lib/utils/handle-error.ts b/web/src/lib/utils/handle-error.ts
index 1e64720159..bdf98e6fab 100644
--- a/web/src/lib/utils/handle-error.ts
+++ b/web/src/lib/utils/handle-error.ts
@@ -1,4 +1,4 @@
-import type { ApiError } from '@api';
+import type { ApiError } from '$lib/utils';
 import axios from 'axios';
 import { notificationController, NotificationType } from '../components/shared-components/notification/notification';
 
diff --git a/web/src/lib/utils/person.ts b/web/src/lib/utils/person.ts
index e608a06a0c..018dbfbb87 100644
--- a/web/src/lib/utils/person.ts
+++ b/web/src/lib/utils/person.ts
@@ -1,4 +1,4 @@
-import type { PersonResponseDto } from '@api';
+import type { PersonResponseDto } from '@immich/sdk';
 
 export const searchNameLocal = (
   name: string,
diff --git a/web/src/lib/utils/timeline-util.ts b/web/src/lib/utils/timeline-util.ts
index e6e33d0b2f..ce9f945e5a 100644
--- a/web/src/lib/utils/timeline-util.ts
+++ b/web/src/lib/utils/timeline-util.ts
@@ -1,4 +1,4 @@
-import type { AssetResponseDto } from '@api';
+import type { AssetResponseDto } from '@immich/sdk';
 import { groupBy, sortBy } from 'lodash-es';
 import { DateTime, Interval } from 'luxon';
 
diff --git a/web/src/routes/(user)/albums/+page.svelte b/web/src/routes/(user)/albums/+page.svelte
index 77b9efeafb..fa0115d828 100644
--- a/web/src/routes/(user)/albums/+page.svelte
+++ b/web/src/routes/(user)/albums/+page.svelte
@@ -8,42 +8,41 @@
 </script>
 
 <script lang="ts">
-  import { albumViewSettings } from '$lib/stores/preferences.store';
-  import AlbumCard from '$lib/components/album-page/album-card.svelte';
   import { goto } from '$app/navigation';
+  import AlbumCard from '$lib/components/album-page/album-card.svelte';
+  import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
+  import Dropdown from '$lib/components/elements/dropdown.svelte';
+  import Icon from '$lib/components/elements/icon.svelte';
+  import TableHeader from '$lib/components/elements/table-header.svelte';
+  import EditAlbumForm from '$lib/components/forms/edit-album-form.svelte';
+  import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
+  import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
   import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
   import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
-  import type { PageData } from './$types';
-  import { useAlbums } from './albums.bloc';
   import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
-  import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
-  import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
-  import { onMount } from 'svelte';
-  import { flip } from 'svelte/animate';
-  import Dropdown from '$lib/components/elements/dropdown.svelte';
-  import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
-  import { AppRoute, dateFormats } from '$lib/constants';
-  import { locale, AlbumViewMode } from '$lib/stores/preferences.store';
-  import {
-    notificationController,
-    NotificationType,
-  } from '$lib/components/shared-components/notification/notification';
-  import type { AlbumResponseDto } from '@api';
-  import TableHeader from '$lib/components/elements/table-header.svelte';
   import FullScreenModal from '$lib/components/shared-components/full-screen-modal.svelte';
-  import EditAlbumForm from '$lib/components/forms/edit-album-form.svelte';
-  import Icon from '$lib/components/elements/icon.svelte';
-  import { orderBy } from 'lodash-es';
   import {
-    mdiPlusBoxOutline,
+    NotificationType,
+    notificationController,
+  } from '$lib/components/shared-components/notification/notification';
+  import { AppRoute, dateFormats } from '$lib/constants';
+  import { AlbumViewMode, albumViewSettings, locale } from '$lib/stores/preferences.store';
+  import type { AlbumResponseDto } from '@immich/sdk';
+  import {
     mdiArrowDownThin,
     mdiArrowUpThin,
+    mdiDeleteOutline,
     mdiFormatListBulletedSquare,
     mdiPencilOutline,
+    mdiPlusBoxOutline,
     mdiTrashCanOutline,
     mdiViewGridOutline,
-    mdiDeleteOutline,
   } from '@mdi/js';
+  import { orderBy } from 'lodash-es';
+  import { onMount } from 'svelte';
+  import { flip } from 'svelte/animate';
+  import type { PageData } from './$types';
+  import { useAlbums } from './albums.bloc';
 
   export let data: PageData;
 
diff --git a/web/src/routes/(user)/albums/[albumId]/+page.svelte b/web/src/routes/(user)/albums/[albumId]/+page.svelte
index 23497b45d9..cdc5e8782f 100644
--- a/web/src/routes/(user)/albums/[albumId]/+page.svelte
+++ b/web/src/routes/(user)/albums/[albumId]/+page.svelte
@@ -46,8 +46,9 @@
   import { getContextMenuPosition } from '$lib/utils/context-menu';
   import { openFileUploadDialog } from '$lib/utils/file-uploader';
   import { handleError } from '$lib/utils/handle-error';
-  import { ReactionLevel, ReactionType, type ActivityResponseDto, type UserResponseDto } from '@api';
   import {
+    ReactionLevel,
+    ReactionType,
     addAssetsToAlbum,
     addUsersToAlbum,
     createActivity,
@@ -57,6 +58,8 @@
     getActivityStatistics,
     getAlbumInfo,
     updateAlbumInfo,
+    type ActivityResponseDto,
+    type UserResponseDto,
   } from '@immich/sdk';
   import {
     mdiArrowLeft,
diff --git a/web/src/routes/(user)/map/+page.svelte b/web/src/routes/(user)/map/+page.svelte
index 3d85160335..b0303d451c 100644
--- a/web/src/routes/(user)/map/+page.svelte
+++ b/web/src/routes/(user)/map/+page.svelte
@@ -10,8 +10,7 @@
   import type { MapSettings } from '$lib/stores/preferences.store';
   import { mapSettings } from '$lib/stores/preferences.store';
   import { featureFlags } from '$lib/stores/server-config.store';
-  import { type MapMarkerResponseDto } from '@api';
-  import { getMapMarkers } from '@immich/sdk';
+  import { getMapMarkers, type MapMarkerResponseDto } from '@immich/sdk';
   import { isEqual } from 'lodash-es';
   import { DateTime, Duration } from 'luxon';
   import { onDestroy, onMount } from 'svelte';
diff --git a/web/src/routes/(user)/people/+page.svelte b/web/src/routes/(user)/people/+page.svelte
index 418cc5ce3e..c28f4d1f6c 100644
--- a/web/src/routes/(user)/people/+page.svelte
+++ b/web/src/routes/(user)/people/+page.svelte
@@ -28,8 +28,15 @@
   import { handleError } from '$lib/utils/handle-error';
   import { searchNameLocal } from '$lib/utils/person';
   import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
-  import { type PeopleUpdateItem, type PersonResponseDto } from '@api';
-  import { getPerson, mergePerson, searchPerson, updatePeople, updatePerson } from '@immich/sdk';
+  import {
+    getPerson,
+    mergePerson,
+    searchPerson,
+    updatePeople,
+    updatePerson,
+    type PeopleUpdateItem,
+    type PersonResponseDto,
+  } from '@immich/sdk';
   import { mdiAccountOff, mdiEyeOutline } from '@mdi/js';
   import { onDestroy, onMount } from 'svelte';
   import type { PageData } from './$types';
diff --git a/web/src/routes/(user)/people/[personId]/+page.svelte b/web/src/routes/(user)/people/[personId]/+page.svelte
index 414257feea..babaca1069 100644
--- a/web/src/routes/(user)/people/[personId]/+page.svelte
+++ b/web/src/routes/(user)/people/[personId]/+page.svelte
@@ -31,6 +31,7 @@
   import { assetViewingStore } from '$lib/stores/asset-viewing.store';
   import { AssetStore } from '$lib/stores/assets.store';
   import { websocketStore } from '$lib/stores/websocket';
+  import { getPeopleThumbnailUrl } from '$lib/utils';
   import { clickOutside } from '$lib/utils/click-outside';
   import { handleError } from '$lib/utils/handle-error';
   import { isExternalUrl } from '$lib/utils/navigation';
@@ -46,7 +47,6 @@
   import { mdiArrowLeft, mdiDotsVertical, mdiPlus } from '@mdi/js';
   import { onMount } from 'svelte';
   import type { PageData } from './$types';
-  import { getPeopleThumbnailUrl } from '$lib/utils';
 
   export let data: PageData;
 
diff --git a/web/src/routes/(user)/places/+page.svelte b/web/src/routes/(user)/places/+page.svelte
index 6237321db0..897d5f9a6f 100644
--- a/web/src/routes/(user)/places/+page.svelte
+++ b/web/src/routes/(user)/places/+page.svelte
@@ -1,11 +1,11 @@
 <script lang="ts">
-  import type { SearchExploreResponseDto } from '@api';
-  import type { PageData } from './$types';
-  import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
-  import { mdiMapMarkerOff } from '@mdi/js';
-  import Icon from '$lib/components/elements/icon.svelte';
-  import { AppRoute } from '$lib/constants';
   import Thumbnail from '$lib/components/assets/thumbnail/thumbnail.svelte';
+  import Icon from '$lib/components/elements/icon.svelte';
+  import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
+  import { AppRoute } from '$lib/constants';
+  import type { SearchExploreResponseDto } from '@immich/sdk';
+  import { mdiMapMarkerOff } from '@mdi/js';
+  import type { PageData } from './$types';
 
   export let data: PageData;
 
diff --git a/web/src/routes/(user)/search/+page.svelte b/web/src/routes/(user)/search/+page.svelte
index f5f8f36d48..e720a39333 100644
--- a/web/src/routes/(user)/search/+page.svelte
+++ b/web/src/routes/(user)/search/+page.svelte
@@ -1,6 +1,10 @@
 <script lang="ts">
+  import { browser } from '$app/environment';
   import { afterNavigate, goto } from '$app/navigation';
   import { page } from '$app/stores';
+  import AlbumCard from '$lib/components/album-page/album-card.svelte';
+  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
+  import Icon from '$lib/components/elements/icon.svelte';
   import AddToAlbum from '$lib/components/photos-page/actions/add-to-album.svelte';
   import ArchiveAction from '$lib/components/photos-page/actions/archive-action.svelte';
   import ChangeDate from '$lib/components/photos-page/actions/change-date-action.svelte';
@@ -14,20 +18,16 @@
   import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
   import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';
   import SearchBar from '$lib/components/shared-components/search-bar/search-bar.svelte';
-  import type { PageData } from './$types';
-  import Icon from '$lib/components/elements/icon.svelte';
-  import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
   import { AppRoute, QueryParameter } from '$lib/constants';
-  import AlbumCard from '$lib/components/album-page/album-card.svelte';
-  import { flip } from 'svelte/animate';
-  import { onDestroy, onMount } from 'svelte';
-  import { browser } from '$app/environment';
   import { assetViewingStore } from '$lib/stores/asset-viewing.store';
   import { preventRaceConditionSearchBar } from '$lib/stores/search.store';
-  import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
-  import { mdiArrowLeft, mdiDotsVertical, mdiImageOffOutline, mdiPlus, mdiSelectAll } from '@mdi/js';
-  import { search, type AssetResponseDto, type SearchResponseDto } from '@immich/sdk';
   import { authenticate } from '$lib/utils/auth';
+  import { shouldIgnoreShortcut } from '$lib/utils/shortcut';
+  import { search, type AssetResponseDto, type SearchResponseDto } from '@immich/sdk';
+  import { mdiArrowLeft, mdiDotsVertical, mdiImageOffOutline, mdiPlus, mdiSelectAll } from '@mdi/js';
+  import { onDestroy, onMount } from 'svelte';
+  import { flip } from 'svelte/animate';
+  import type { PageData } from './$types';
 
   export let data: PageData;
 
diff --git a/web/src/routes/(user)/share/[key]/+page.svelte b/web/src/routes/(user)/share/[key]/+page.svelte
index 85df17afb6..78c2a97dd1 100644
--- a/web/src/routes/(user)/share/[key]/+page.svelte
+++ b/web/src/routes/(user)/share/[key]/+page.svelte
@@ -7,8 +7,7 @@
   import ThemeButton from '$lib/components/shared-components/theme-button.svelte';
   import { user } from '$lib/stores/user.store';
   import { handleError } from '$lib/utils/handle-error';
-  import { SharedLinkType } from '@api';
-  import { getMySharedLink } from '@immich/sdk';
+  import { getMySharedLink, SharedLinkType } from '@immich/sdk';
   import type { PageData } from './$types';
 
   export let data: PageData;
diff --git a/web/src/routes/(user)/share/[key]/+page.ts b/web/src/routes/(user)/share/[key]/+page.ts
index 938a3bc9d9..a4327a832d 100644
--- a/web/src/routes/(user)/share/[key]/+page.ts
+++ b/web/src/routes/(user)/share/[key]/+page.ts
@@ -1,7 +1,6 @@
 import { getAssetThumbnailUrl } from '$lib/utils';
 import { authenticate } from '$lib/utils/auth';
-import { ThumbnailFormat } from '@api';
-import { getMySharedLink } from '@immich/sdk';
+import { ThumbnailFormat, getMySharedLink } from '@immich/sdk';
 import { error as throwError } from '@sveltejs/kit';
 import type { AxiosError } from 'axios';
 import type { PageLoad } from './$types';
diff --git a/web/src/routes/(user)/sharing/sharedlinks/+page.svelte b/web/src/routes/(user)/sharing/sharedlinks/+page.svelte
index 60713c305f..394e74faf8 100644
--- a/web/src/routes/(user)/sharing/sharedlinks/+page.svelte
+++ b/web/src/routes/(user)/sharing/sharedlinks/+page.svelte
@@ -10,9 +10,9 @@
   import SharedLinkCard from '$lib/components/sharedlinks-page/shared-link-card.svelte';
   import { AppRoute } from '$lib/constants';
   import { serverConfig } from '$lib/stores/server-config.store';
+  import { copyToClipboard, makeSharedLinkUrl } from '$lib/utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { copyToClipboard, makeSharedLinkUrl, type SharedLinkResponseDto } from '@api';
-  import { getAllSharedLinks, removeSharedLink } from '@immich/sdk';
+  import { getAllSharedLinks, removeSharedLink, type SharedLinkResponseDto } from '@immich/sdk';
   import { mdiArrowLeft } from '@mdi/js';
   import { onMount } from 'svelte';
 
diff --git a/web/src/routes/+error.svelte b/web/src/routes/+error.svelte
index 93cadacca9..2f5d0ab51e 100644
--- a/web/src/routes/+error.svelte
+++ b/web/src/routes/+error.svelte
@@ -2,8 +2,8 @@
   import { page } from '$app/stores';
   import Icon from '$lib/components/elements/icon.svelte';
   import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
+  import { copyToClipboard } from '$lib/utils';
   import { mdiCodeTags, mdiContentCopy, mdiMessage, mdiPartyPopper } from '@mdi/js';
-  import { copyToClipboard } from '../api/utils';
 
   const handleCopy = async () => {
     //
diff --git a/web/src/routes/admin/repair/+page.svelte b/web/src/routes/admin/repair/+page.svelte
index da0cbc9e71..939e151f5d 100644
--- a/web/src/routes/admin/repair/+page.svelte
+++ b/web/src/routes/admin/repair/+page.svelte
@@ -2,6 +2,7 @@
   import empty4Url from '$lib/assets/empty-4.svg';
   import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
   import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
+  import Icon from '$lib/components/elements/icon.svelte';
   import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
   import EmptyPlaceholder from '$lib/components/shared-components/empty-placeholder.svelte';
   import {
@@ -9,13 +10,12 @@
     notificationController,
   } from '$lib/components/shared-components/notification/notification';
   import { downloadManager } from '$lib/stores/download';
+  import { copyToClipboard } from '$lib/utils';
   import { downloadBlob } from '$lib/utils/asset-utils';
   import { handleError } from '$lib/utils/handle-error';
-  import { type FileReportItemDto, copyToClipboard } from '@api';
-  import Icon from '$lib/components/elements/icon.svelte';
+  import { fixAuditFiles, getAuditFiles, getFileChecksums, type FileReportItemDto } from '@immich/sdk';
+  import { mdiCheckAll, mdiContentCopy, mdiDownload, mdiRefresh, mdiWrench } from '@mdi/js';
   import type { PageData } from './$types';
-  import { mdiWrench, mdiCheckAll, mdiDownload, mdiRefresh, mdiContentCopy } from '@mdi/js';
-  import { fixAuditFiles, getAuditFiles, getFileChecksums } from '@immich/sdk';
 
   export let data: PageData;
 
diff --git a/web/src/routes/admin/system-settings/+page.svelte b/web/src/routes/admin/system-settings/+page.svelte
index 8bf63d58c6..f8062e6211 100644
--- a/web/src/routes/admin/system-settings/+page.svelte
+++ b/web/src/routes/admin/system-settings/+page.svelte
@@ -1,29 +1,29 @@
 <script lang="ts">
+  import AdminSettings from '$lib/components/admin-page/settings/admin-settings.svelte';
   import FFmpegSettings from '$lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte';
   import JobSettings from '$lib/components/admin-page/settings/job-settings/job-settings.svelte';
+  import LibrarySettings from '$lib/components/admin-page/settings/library-settings/library-settings.svelte';
+  import LoggingSettings from '$lib/components/admin-page/settings/logging-settings/logging-settings.svelte';
   import MachineLearningSettings from '$lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte';
   import MapSettings from '$lib/components/admin-page/settings/map-settings/map-settings.svelte';
+  import NewVersionCheckSettings from '$lib/components/admin-page/settings/new-version-check-settings/new-version-check-settings.svelte';
   import OAuthSettings from '$lib/components/admin-page/settings/oauth/oauth-settings.svelte';
   import PasswordLoginSettings from '$lib/components/admin-page/settings/password-login/password-login-settings.svelte';
+  import ServerSettings from '$lib/components/admin-page/settings/server/server-settings.svelte';
   import SettingAccordion from '$lib/components/admin-page/settings/setting-accordion.svelte';
   import StorageTemplateSettings from '$lib/components/admin-page/settings/storage-template/storage-template-settings.svelte';
-  import ThumbnailSettings from '$lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte';
-  import ServerSettings from '$lib/components/admin-page/settings/server/server-settings.svelte';
-  import TrashSettings from '$lib/components/admin-page/settings/trash-settings/trash-settings.svelte';
   import ThemeSettings from '$lib/components/admin-page/settings/theme/theme-settings.svelte';
+  import ThumbnailSettings from '$lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte';
+  import TrashSettings from '$lib/components/admin-page/settings/trash-settings/trash-settings.svelte';
   import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
+  import Icon from '$lib/components/elements/icon.svelte';
   import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
   import { downloadManager } from '$lib/stores/download';
   import { featureFlags } from '$lib/stores/server-config.store';
+  import { copyToClipboard } from '$lib/utils';
   import { downloadBlob } from '$lib/utils/asset-utils';
-  import { copyToClipboard } from '@api';
-  import Icon from '$lib/components/elements/icon.svelte';
-  import type { PageData } from './$types';
-  import NewVersionCheckSettings from '$lib/components/admin-page/settings/new-version-check-settings/new-version-check-settings.svelte';
-  import LibrarySettings from '$lib/components/admin-page/settings/library-settings/library-settings.svelte';
-  import LoggingSettings from '$lib/components/admin-page/settings/logging-settings/logging-settings.svelte';
   import { mdiAlert, mdiContentCopy, mdiDownload } from '@mdi/js';
-  import AdminSettings from '$lib/components/admin-page/settings/admin-settings.svelte';
+  import type { PageData } from './$types';
 
   export let data: PageData;
 
diff --git a/web/src/test-data/factories/user-factory.ts b/web/src/test-data/factories/user-factory.ts
index ac16a32e49..db20074d28 100644
--- a/web/src/test-data/factories/user-factory.ts
+++ b/web/src/test-data/factories/user-factory.ts
@@ -1,5 +1,5 @@
-import { UserAvatarColor, type UserResponseDto } from '@api';
 import { faker } from '@faker-js/faker';
+import { UserAvatarColor, type UserResponseDto } from '@immich/sdk';
 import { Sync } from 'factory.ts';
 
 export const userFactory = Sync.makeFactory<UserResponseDto>({
diff --git a/web/svelte.config.js b/web/svelte.config.js
index 987b5f4d85..c6ff761400 100644
--- a/web/svelte.config.js
+++ b/web/svelte.config.js
@@ -23,7 +23,6 @@ const config = {
     alias: {
       $lib: 'src/lib',
       '$lib/*': 'src/lib/*',
-      '@api': 'src/api',
       '@test-data': 'src/test-data',
     },
   },
diff --git a/web/vite.config.js b/web/vite.config.js
index f26b1bf614..7594ea3424 100644
--- a/web/vite.config.js
+++ b/web/vite.config.js
@@ -17,7 +17,6 @@ export default defineConfig({
       'xmlhttprequest-ssl': './node_modules/engine.io-client/lib/xmlhttprequest.js',
       // eslint-disable-next-line unicorn/prefer-module
       '@test-data': path.resolve(__dirname, './src/test-data'),
-      '@api': path.resolve('./src/api'),
     },
   },
   server: {