diff --git a/docs/content/references/config/general.md b/docs/content/references/config/general.md
index 11bbf39df..91230101a 100644
--- a/docs/content/references/config/general.md
+++ b/docs/content/references/config/general.md
@@ -6,6 +6,7 @@
 | `HD_BACKEND_PORT`        | 3000                   |                             | The port the backend process listens on.                                                                                                               |
 | `HD_FRONTEND_PORT`       | 3001                   |                             | The port the frontend process listens on.                                                                                                              |
 | `HD_RENDERER_BASE_URL`   | Content of HD_BASE_URL |                             | The URL the renderer runs on. If omitted this will be the same as `HD_BASE_URL`. For more detail see [this faq entry][faq-entry]                       |
+| `HD_INTERNAL_API_URL`    | Content of HD_BASE_URL | `http://localhost:3000`     | This URL is used by the frontend to access the backend directly if it can't reach the backend using the `HD_BASE_URL`                                  |
 | `HD_LOGLEVEL`            | warn                   |                             | The loglevel that should be used. Options are `error`, `warn`, `info`, `debug` or `trace`.                                                             |
 | `HD_SHOW_LOG_TIMESTAMP`  | true                   |                             | Specifies if a timestamp should be added to the log statements. Disabling is useful for extern log management (systemd etc.)                           |
 | `HD_FORBIDDEN_NOTE_IDS`  | -                      | `notAllowed,alsoNotAllowed` | A list of note ids (separated by `,`), that are not allowed to be created or requested by anyone.                                                      |
diff --git a/frontend/src/api/alias/index.ts b/frontend/src/api/alias/index.ts
index 1662a94af..9bb398c0c 100644
--- a/frontend/src/api/alias/index.ts
+++ b/frontend/src/api/alias/index.ts
@@ -14,7 +14,7 @@ import type { Alias, NewAliasDto, PrimaryAliasDto } from './types'
  * @param noteIdOrAlias The note id or an existing alias for a note.
  * @param newAlias The new alias.
  * @return Information about the newly created alias.
- * @throws {Error} when the api request wasn't successfull
+ * @throws {Error} when the api request wasn't successful
  */
 export const addAlias = async (noteIdOrAlias: string, newAlias: string): Promise<Alias> => {
   const response = await new PostApiRequestBuilder<Alias, NewAliasDto>('alias')
diff --git a/frontend/src/api/common/api-request-builder/api-request-builder.ts b/frontend/src/api/common/api-request-builder/api-request-builder.ts
index 7c57242cb..290a23de5 100644
--- a/frontend/src/api/common/api-request-builder/api-request-builder.ts
+++ b/frontend/src/api/common/api-request-builder/api-request-builder.ts
@@ -8,6 +8,7 @@ import type { ApiErrorResponse } from '../api-error-response'
 import { ApiResponse } from '../api-response'
 import { defaultConfig, defaultHeaders } from '../default-config'
 import deepmerge from 'deepmerge'
+import { baseUrlFromEnvExtractor } from '../../../utils/base-url-from-env-extractor'
 
 /**
  * Builder to construct and execute a call to the HTTP API.
@@ -27,7 +28,18 @@ export abstract class ApiRequestBuilder<ResponseType> {
    * @param baseUrl An optional base URL that is used for the endpoint
    */
   constructor(endpoint: string, baseUrl?: string) {
-    this.targetUrl = `${baseUrl ?? '/'}api/private/${endpoint}`
+    const actualBaseUrl = this.determineBaseUrl(baseUrl)
+
+    this.targetUrl = `${actualBaseUrl}api/private/${endpoint}`
+  }
+
+  /**
+   * Determines the API base URL by checking if the request is made on the server or client
+   *
+   * @return the base url
+   */
+  private determineBaseUrl(baseUrl?: string) {
+    return typeof window !== 'undefined' ? baseUrl ?? '/' : baseUrlFromEnvExtractor.extractBaseUrls().internalApiUrl
   }
 
   protected async sendRequestAndVerifyResponse(httpMethod: RequestInit['method']): Promise<ApiResponse<ResponseType>> {
diff --git a/frontend/src/components/common/base-url/base-url-context-provider.tsx b/frontend/src/components/common/base-url/base-url-context-provider.tsx
index aa4d2c926..17e8d2482 100644
--- a/frontend/src/components/common/base-url/base-url-context-provider.tsx
+++ b/frontend/src/components/common/base-url/base-url-context-provider.tsx
@@ -10,6 +10,7 @@ import React, { createContext } from 'react'
 export interface BaseUrls {
   renderer: string
   editor: string
+  internalApiUrl: string
 }
 
 interface BaseUrlContextProviderProps {
diff --git a/frontend/src/utils/base-url-from-env-extractor.spec.ts b/frontend/src/utils/base-url-from-env-extractor.spec.ts
index cbf66b3af..e9b83d112 100644
--- a/frontend/src/utils/base-url-from-env-extractor.spec.ts
+++ b/frontend/src/utils/base-url-from-env-extractor.spec.ts
@@ -6,71 +6,93 @@
 import { BaseUrlFromEnvExtractor } from './base-url-from-env-extractor'
 
 describe('BaseUrlFromEnvExtractor', () => {
-  it('should return the base urls if both are valid urls', () => {
+  it('should return the base urls if all are valid urls', () => {
     process.env.HD_BASE_URL = 'https://editor.example.org/'
     process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/'
+
     const sut = new BaseUrlFromEnvExtractor()
 
     expect(sut.extractBaseUrls()).toStrictEqual({
       renderer: 'https://renderer.example.org/',
+      internalApiUrl: 'https://internal.example.org/',
       editor: 'https://editor.example.org/'
     })
   })
 
-  it('should return an empty optional if no var is set', () => {
+  it('should throw if no var is set', () => {
     process.env.HD_BASE_URL = undefined
     process.env.HD_RENDERER_BASE_URL = undefined
+    process.env.HD_INTERNAL_API_URL = undefined
     const sut = new BaseUrlFromEnvExtractor()
 
     expect(() => sut.extractBaseUrls()).toThrow()
   })
 
-  it("should return an empty optional if editor base url isn't an URL", () => {
+  it("should throw if editor base url isn't an URL", () => {
     process.env.HD_BASE_URL = 'bibedibabedibu'
     process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/'
     const sut = new BaseUrlFromEnvExtractor()
 
     expect(() => sut.extractBaseUrls()).toThrow()
   })
 
-  it("should return an empty optional if renderer base url isn't an URL", () => {
+  it("should throw if renderer base url isn't an URL", () => {
     process.env.HD_BASE_URL = 'https://editor.example.org/'
     process.env.HD_RENDERER_BASE_URL = 'bibedibabedibu'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/'
     const sut = new BaseUrlFromEnvExtractor()
 
     expect(() => sut.extractBaseUrls()).toThrow()
   })
 
-  it("should return an optional if editor base url isn't ending with a slash", () => {
-    process.env.HD_BASE_URL = 'https://editor.example.org'
+  it("should throw if internal api url isn't an URL", () => {
+    process.env.HD_BASE_URL = 'https://editor.example.org/'
     process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/'
+    process.env.HD_INTERNAL_API_URL = 'bibedibabedibu'
     const sut = new BaseUrlFromEnvExtractor()
 
-    expect(sut.extractBaseUrls()).toStrictEqual({
-      renderer: 'https://renderer.example.org/',
-      editor: 'https://editor.example.org/'
-    })
+    expect(() => sut.extractBaseUrls()).toThrow()
   })
 
-  it("should return an optional if renderer base url isn't ending with a slash", () => {
-    process.env.HD_BASE_URL = 'https://editor.example.org/'
-    process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org'
+  it('should throw if editor base url contains a subdirectory', () => {
+    process.env.HD_BASE_URL = 'https://editor.example.org/asd/'
+    process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/'
     const sut = new BaseUrlFromEnvExtractor()
 
-    expect(sut.extractBaseUrls()).toStrictEqual({
-      renderer: 'https://renderer.example.org/',
-      editor: 'https://editor.example.org/'
-    })
+    expect(() => sut.extractBaseUrls()).toThrow()
   })
 
-  it('should copy editor base url to renderer base url if renderer base url is omitted', () => {
+  it('should throw if renderer base url contains a subdirectory', () => {
     process.env.HD_BASE_URL = 'https://editor.example.org/'
+    process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/asd/'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/'
+    const sut = new BaseUrlFromEnvExtractor()
+
+    expect(() => sut.extractBaseUrls()).toThrow()
+  })
+
+  it('should throw if internal api url contains a subdirectory', () => {
+    process.env.HD_BASE_URL = 'https://editor.example.org/'
+    process.env.HD_RENDERER_BASE_URL = 'https://renderer.example.org/'
+    process.env.HD_INTERNAL_API_URL = 'https://internal.example.org/asd/'
+    const sut = new BaseUrlFromEnvExtractor()
+
+    expect(() => sut.extractBaseUrls()).toThrow()
+  })
+
+  it('should copy editor base url to renderer base/internal api url if url is omitted', () => {
+    process.env.HD_BASE_URL = 'https://editor1.example.org/'
     delete process.env.HD_RENDERER_BASE_URL
+    delete process.env.HD_INTERNAL_API_URL
     const sut = new BaseUrlFromEnvExtractor()
 
     expect(sut.extractBaseUrls()).toStrictEqual({
-      renderer: 'https://editor.example.org/',
-      editor: 'https://editor.example.org/'
+      renderer: 'https://editor1.example.org/',
+      internalApiUrl: 'https://editor1.example.org/',
+      editor: 'https://editor1.example.org/'
     })
   })
 })
diff --git a/frontend/src/utils/base-url-from-env-extractor.ts b/frontend/src/utils/base-url-from-env-extractor.ts
index 72a74b7f4..6767b0fbf 100644
--- a/frontend/src/utils/base-url-from-env-extractor.ts
+++ b/frontend/src/utils/base-url-from-env-extractor.ts
@@ -16,7 +16,7 @@ export class BaseUrlFromEnvExtractor {
   private baseUrls: BaseUrls | undefined
   private readonly logger = new Logger('Base URL Configuration')
 
-  private extractUrlFromEnvVar(envVarName: string, envVarValue: string | undefined): Optional<URL> {
+  private extractUrlFromEnvVar(envVarValue: string | undefined): Optional<URL> {
     try {
       return parseUrl(envVarValue)
     } catch (error) {
@@ -30,36 +30,39 @@ export class BaseUrlFromEnvExtractor {
   }
 
   private extractEditorBaseUrlFromEnv(): Optional<URL> {
-    const envValue = this.extractUrlFromEnvVar('HD_BASE_URL', process.env.HD_BASE_URL)
+    const envValue = this.extractUrlFromEnvVar(process.env.HD_BASE_URL)
     if (envValue.isEmpty()) {
       this.logger.error("HD_BASE_URL isn't a valid URL!")
     }
     return envValue
   }
 
-  private extractRendererBaseUrlFromEnv(editorBaseUrl: URL): Optional<URL> {
+  private extractUrlFromEnv(editorBaseUrl: URL, envVarName: string): Optional<URL> {
     if (isTestMode) {
-      this.logger.info('Test mode activated. Using editor base url for renderer.')
+      this.logger.info(`Test mode activated. Using editor base url for ${envVarName}.`)
       return Optional.of(editorBaseUrl)
     }
 
-    if (!process.env.HD_RENDERER_BASE_URL) {
-      this.logger.info('HD_RENDERER_BASE_URL is unset. Using editor base url for renderer.')
+    if (!process.env[envVarName]) {
+      this.logger.info(`${envVarName} is unset. Using editor base url.`)
       return Optional.of(editorBaseUrl)
     }
 
-    return this.extractUrlFromEnvVar('HD_RENDERER_BASE_URL', process.env.HD_RENDERER_BASE_URL)
+    return this.extractUrlFromEnvVar(process.env[envVarName])
   }
 
   private renewBaseUrls(): BaseUrls {
     return this.extractEditorBaseUrlFromEnv()
       .flatMap((editorBaseUrl) =>
-        this.extractRendererBaseUrlFromEnv(editorBaseUrl).map((rendererBaseUrl) => {
-          return {
-            editor: editorBaseUrl.toString(),
-            renderer: rendererBaseUrl.toString()
-          }
-        })
+        this.extractUrlFromEnv(editorBaseUrl, 'HD_RENDERER_BASE_URL').flatMap((rendererBaseUrl) =>
+          this.extractUrlFromEnv(editorBaseUrl, 'HD_INTERNAL_API_URL').map((internalApiUrl) => {
+            return {
+              editor: editorBaseUrl.toString(),
+              renderer: rendererBaseUrl.toString(),
+              internalApiUrl: internalApiUrl.toString()
+            }
+          })
+        )
       )
       .orElseThrow(() => new Error('couldnt parse env vars'))
   }
@@ -73,7 +76,8 @@ export class BaseUrlFromEnvExtractor {
     if (isBuildTime) {
       return {
         editor: 'https://example.org/',
-        renderer: 'https://example.org/'
+        renderer: 'https://example.org/',
+        internalApiUrl: 'https://example.org/'
       }
     }
 
@@ -90,6 +94,7 @@ export class BaseUrlFromEnvExtractor {
     }
     this.logger.info('Editor base URL', this.baseUrls.editor.toString())
     this.logger.info('Renderer base URL', this.baseUrls.renderer.toString())
+    this.logger.info('Internal API URL', this.baseUrls.internalApiUrl.toString())
   }
 }