diff --git a/.helm/adhoc/configmap-siibra-explorer.yml b/.helm/adhoc/configmap-siibra-explorer.yml
index 37fbb9fc0d6753f5a560085faeae13c8f0c96f3e..4bc6d90b16e6421ffe24e3e19c5b5e37c76ee29d 100644
--- a/.helm/adhoc/configmap-siibra-explorer.yml
+++ b/.helm/adhoc/configmap-siibra-explorer.yml
@@ -7,6 +7,8 @@ data:
   REDIS_ADDR: "cache-redis-service"
   V2_7_PLUGIN_URLS: "https://siibra-jugex.apps.tc.humanbrainproject.eu/viewer_plugin/manifest.json;https://ngpy.apps.hbp.eu/viewer_plugin/manifest.json"
   LOGGER_DIR: "/sxplr-log"
+  OVERWRITE_API_ENDPOINT: https://siibra-api-prod.apps.tc.humanbrainproject.eu/v3_0
+  OVERWRITE_SPATIAL_ENDPOINT: 'https://siibra-spatial-backend.apps.tc.humanbrainproject.eu'
 
 kind: ConfigMap
 metadata:
diff --git a/.helm/adhoc/example-secret-siibra-explorer.yml b/.helm/adhoc/example-secret-siibra-explorer.yml
index e4118f80194842f5a40ffc849eec748fd4ce2180..c1c93e8a5bc964fffb67d8152ebf327664a5d2ed 100644
--- a/.helm/adhoc/example-secret-siibra-explorer.yml
+++ b/.helm/adhoc/example-secret-siibra-explorer.yml
@@ -7,7 +7,6 @@ data:
   # n.b. echo -n "foobar" | base64
   # or else the new line will also be encoded, and you will
   # wonder why your application does not work
-  OVERWRITE_API_ENDPOINT: Zm9vYmFy
   HBP_CLIENTID_V2: Zm9vYmFy
   HBP_CLIENTSECRET_V2: Zm9vYmFy
   SXPLR_EBRAINS_IAM_SA_CLIENT_ID: Zm9vYmFy
diff --git a/backend/app/config.py b/backend/app/config.py
index bc824fd52776656cb2cbaf480f918d091a342e51..43f49b315245a838efafca87ba3cac56d47c94fb 100644
--- a/backend/app/config.py
+++ b/backend/app/config.py
@@ -8,6 +8,8 @@ HOSTNAME = os.getenv("HOSTNAME", "http://localhost:3000")
 
 OVERWRITE_API_ENDPOINT = os.getenv("OVERWRITE_API_ENDPOINT")
 
+OVERWRITE_SPATIAL_ENDPOINT = os.getenv("OVERWRITE_SPATIAL_ENDPOINT")
+
 LOCAL_CDN = os.getenv("LOCAL_CDN")
 
 HBP_CLIENTID_V2 = os.getenv("HBP_CLIENTID_V2", "no hbp id")
diff --git a/backend/app/const.py b/backend/app/const.py
index 9948b8e477d84b697da868c485ae17b117680ccc..ca720149957d66ec98f8379492579c6d10afea5b 100644
--- a/backend/app/const.py
+++ b/backend/app/const.py
@@ -19,3 +19,5 @@ SCOPES =  [
 DATA_ERROR_ATTR = "data-error"
 
 OVERWRITE_SAPI_ENDPOINT_ATTR = "x-sapi-base-url"
+
+OVERWRITE_SPATIAL_BACKEND_ATTR = "x-spatial-backend-url"
diff --git a/backend/app/index_html.py b/backend/app/index_html.py
index 903ec154768b2875a28b67a511a40da9b97d3d86..ea4baf68fce8a5748ca262a04f907248bd3031ce 100644
--- a/backend/app/index_html.py
+++ b/backend/app/index_html.py
@@ -2,8 +2,8 @@ from fastapi import APIRouter, Request
 from pathlib import Path
 from fastapi.responses import Response
 from typing import Dict
-from .const import ERROR_KEY, DATA_ERROR_ATTR, OVERWRITE_SAPI_ENDPOINT_ATTR, COOKIE_KWARGS
-from .config import PATH_TO_PUBLIC, OVERWRITE_API_ENDPOINT
+from .const import ERROR_KEY, DATA_ERROR_ATTR, OVERWRITE_SAPI_ENDPOINT_ATTR, COOKIE_KWARGS, OVERWRITE_SPATIAL_BACKEND_ATTR
+from .config import PATH_TO_PUBLIC, OVERWRITE_API_ENDPOINT, OVERWRITE_SPATIAL_ENDPOINT
 
 path_to_index = Path(PATH_TO_PUBLIC) / "index.html"
 index_html: str = None
@@ -32,6 +32,8 @@ async def get_index_html(request: Request):
     if OVERWRITE_API_ENDPOINT:
         attributes_to_append[OVERWRITE_SAPI_ENDPOINT_ATTR] = OVERWRITE_API_ENDPOINT
     
+    if OVERWRITE_SPATIAL_ENDPOINT:
+        attributes_to_append[OVERWRITE_SPATIAL_BACKEND_ATTR] = OVERWRITE_SPATIAL_ENDPOINT
 
     attr_string = " ".join([f"{key}={_monkey_sanitize(value)}" for key, value in attributes_to_append.items()])
 
diff --git a/common/constants.js b/common/constants.js
index fb5a018be88f017fb2b1767e07a7305288fb7b03..4ddf697531624b02c7cb8934dd2a9d2cb348859c 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -150,7 +150,8 @@ If you do not accept the Terms & Conditions you are not permitted to access or u
     AUXMESH_DESC: `Some templates contain auxiliary meshes, which compliment the appearance of the template in the perspective view.`,
 
     OVERWRITE_SAPI_ENDPOINT_ATTR: `x-sapi-base-url`,
-    DATA_ERROR_ATTR: `data-error`
+    OVERWRITE_SPATIAL_BACKEND_ATTR: `x-spatial-backend-url`,
+    DATA_ERROR_ATTR: `data-error`,
   }
 
   exports.QUICKTOUR_DESC ={
diff --git a/deploy_env.md b/deploy_env.md
index 8c2b1a3d8623a6937f4ce8956eab4fe3e6daceda..00df9cfd338132989d45dd9521b3a153c4e3cc7f 100644
--- a/deploy_env.md
+++ b/deploy_env.md
@@ -9,6 +9,7 @@
 | `V2_7_STAGING_PLUGIN_URLS` | semi colon separated urls to be returned when user queries plugins | `''`
 | `BUILD_TEXT` | overlay text at bottom right of the viewer. set to `''` to hide. | |
 | `OVERWRITE_API_ENDPOINT` | overwrite build time siibra-api endpoint |
+| `OVERWRITE_SPATIAL_ENDPOINT` | overwrite build time spatial transform endpoint | |
 | `PATH_TO_PUBLIC` | path to built frontend | `../dist/aot` |
 
 
diff --git a/docs/releases/v2.14.5.md b/docs/releases/v2.14.5.md
index da8180f83392263b1c09cbe4f9b43794e253e824..a1c15104ac8d92556681f6bf5be939a3f8f31151 100644
--- a/docs/releases/v2.14.5.md
+++ b/docs/releases/v2.14.5.md
@@ -18,3 +18,4 @@
 - Removed dependency on connectivity-component
 - Removed reference to JSC OKD instance, as the instance is no longer available
 - Updated google-site-verification
+- Allow inter space transform to be configured at runtime
diff --git a/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.spec.ts b/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.spec.ts
index 30542d6fc0441e31a41fc7ac5b372208ede998d1..c9baedadf1fea46ba91d1354427e54fe39503f55 100644
--- a/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.spec.ts
+++ b/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.spec.ts
@@ -1,16 +1,25 @@
 import { InterSpaceCoordXformSvc, VALID_TEMPLATE_SPACE_NAMES } from './interSpaceCoordXform.service'
 import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'
 import { TestBed, fakeAsync, tick } from '@angular/core/testing'
+import { GET_ATTR_TOKEN } from 'src/util/constants'
 
 describe('InterSpaceCoordXformSvc.service.spec.ts', () => {
   describe('InterSpaceCoordXformSvc', () => {
+    let attr: string = null
+    const defaultUrl = 'https://hbp-spatial-backend.apps.hbp.eu/v1/transform-points'
     beforeEach(() => {
       TestBed.configureTestingModule({
         imports: [
           HttpClientTestingModule
         ],
         providers: [
-          InterSpaceCoordXformSvc
+          InterSpaceCoordXformSvc,
+          {
+            provide: GET_ATTR_TOKEN,
+            useFactory: () => {
+              return () => attr
+            }
+          }
         ]
       })
     })
@@ -39,7 +48,7 @@ describe('InterSpaceCoordXformSvc.service.spec.ts', () => {
         ).subscribe((_ev) => {
           
         })
-        const req = httpTestingController.expectOne(service['url'])
+        const req = httpTestingController.expectOne(defaultUrl)
         expect(req.request.method).toEqual('POST')
         expect(
           JSON.parse(req.request.body)
@@ -67,7 +76,7 @@ describe('InterSpaceCoordXformSvc.service.spec.ts', () => {
           expect(status).toEqual('completed')
           expect(result).toEqual([1e6, 2e6, 3e6])
         })
-        const req = httpTestingController.expectOne(service['url'])
+        const req = httpTestingController.expectOne(defaultUrl)
         req.flush({
           'target_points':[
             [1, 2, 3]
@@ -87,7 +96,7 @@ describe('InterSpaceCoordXformSvc.service.spec.ts', () => {
           expect(status).toEqual('error')
           done()
         })
-        const req = httpTestingController.expectOne(service['url'])
+        const req = httpTestingController.expectOne(defaultUrl)
         
         req.flush('intercepted', { status: 500, statusText: 'internal server error' })
       })
@@ -105,10 +114,36 @@ describe('InterSpaceCoordXformSvc.service.spec.ts', () => {
           expect(status).toEqual('error')
           expect(statusText).toEqual(`Timeout after 3s`)
         })
-        const req = httpTestingController.expectOne(service['url'])
+        const req = httpTestingController.expectOne(defaultUrl)
         tick(4000)
         expect(req.cancelled).toBe(true)
       }))
+
+      describe("if injected override endpoint", () => {
+        beforeEach(() => {
+          attr = "http://foo-bar/"
+        })
+        afterEach(() => {
+          attr = null
+        })
+        it("trasnforms argument properly", () => {
+          
+          const service = TestBed.inject(InterSpaceCoordXformSvc)
+          const httpTestingController = TestBed.inject(HttpTestingController)
+
+          // subscriptions are necessary for http fetch to occur
+          service.transform(
+            VALID_TEMPLATE_SPACE_NAMES.MNI152,
+            VALID_TEMPLATE_SPACE_NAMES.BIG_BRAIN,
+            [1,2,3]
+          ).subscribe((_ev) => {
+            
+          })
+          const req = httpTestingController.expectOne("http://foo-bar/v1/transform-points")
+          expect(req.request.method).toEqual('POST')
+          req.flush({})
+        })
+      })
     })
   })
 })
diff --git a/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.ts b/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.ts
index 8dff3f67d6bbc69939068718270e487ee3bbeb2c..18518da170f3c2d70e3839d0cfc611cdf8133d4f 100644
--- a/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.ts
+++ b/src/atlasComponents/sapi/core/space/interSpaceCoordXform.service.ts
@@ -1,9 +1,11 @@
-import { Injectable } from "@angular/core";
+import { Inject, Injectable } from "@angular/core";
 import { HttpClient, HttpHeaders, HttpErrorResponse } from "@angular/common/http";
 import { catchError, timeout, map } from "rxjs/operators";
 import { of, Observable } from "rxjs";
 import { environment } from 'src/environments/environment'
 import { IDS } from "src/atlasComponents/sapi/constants"
+import { GET_ATTR_TOKEN, GetAttr } from "src/util/constants";
+import { CONST } from "common/constants"
 
 type ITemplateCoordXformResp = {
   status: 'pending' | 'error' | 'completed' | 'cached'
@@ -49,9 +51,11 @@ export class InterSpaceCoordXformSvc {
     }
   }
 
-  constructor(private httpClient: HttpClient) {}
+  constructor(private httpClient: HttpClient, @Inject(GET_ATTR_TOKEN) getAttr: GetAttr) {
+    this.url = (getAttr(CONST.OVERWRITE_SPATIAL_BACKEND_ATTR) || environment.SPATIAL_TRANSFORM_BACKEND).replace(/\/$/, '') + '/v1/transform-points'
+  }
 
-  private url = `${environment.SPATIAL_TRANSFORM_BACKEND.replace(/\/$/, '')}/v1/transform-points`
+  private url: string
 
   // jasmine marble cannot test promise properly
   // see https://github.com/ngrx/platform/issues/498#issuecomment-337465179
diff --git a/src/main.module.ts b/src/main.module.ts
index 2735d71ea4b665116e3e090e446e166ac53049fa..aedbee438fac95a83a983c2704b2a7cee7bdb00d 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -53,6 +53,7 @@ import { CONST } from "common/constants"
 import { ViewerCommonEffects } from './viewerModule';
 import { environment } from './environments/environment';
 import { SAPI } from './atlasComponents/sapi';
+import { GET_ATTR_TOKEN, GetAttr } from './util/constants';
 
 @NgModule({
   imports: [
@@ -187,12 +188,20 @@ import { SAPI } from './atlasComponents/sapi';
       multi: true,
       deps: [ AuthService, Store ]
     },
+    {
+      provide: GET_ATTR_TOKEN,
+      useFactory: (document: Document) => {
+        return (attr: string) => {
+          const rootEl = document.querySelector("atlas-viewer")
+          return rootEl?.getAttribute(attr)
+        }
+      },
+      deps: [ DOCUMENT ]
+    },
     {
       provide: APP_INITIALIZER,
-      useFactory: (sapi: SAPI, document: Document) => {
-        
-        const rootEl = document.querySelector("atlas-viewer")
-        const overwriteSapiUrl = rootEl?.getAttribute(CONST.OVERWRITE_SAPI_ENDPOINT_ATTR)
+      useFactory: (sapi: SAPI, getAttr: GetAttr) => {
+        const overwriteSapiUrl = getAttr(CONST.OVERWRITE_SAPI_ENDPOINT_ATTR)
         
         const { SIIBRA_API_ENDPOINTS } = environment
         const endpoints = (overwriteSapiUrl && [ overwriteSapiUrl ]) || SIIBRA_API_ENDPOINTS.split(',')
@@ -207,7 +216,7 @@ import { SAPI } from './atlasComponents/sapi';
         }
       },
       multi: true,
-      deps: [ SAPI, DOCUMENT ]
+      deps: [ SAPI, GET_ATTR_TOKEN ]
     }
   ],
   bootstrap: [
diff --git a/src/state/atlasSelection/effects.spec.ts b/src/state/atlasSelection/effects.spec.ts
index a64b032338706a3342829d8337ba855ffc116965..aeefa764aaa2fe86cf15ed76ca11d16599f6061e 100644
--- a/src/state/atlasSelection/effects.spec.ts
+++ b/src/state/atlasSelection/effects.spec.ts
@@ -3,7 +3,7 @@ import { provideMockActions } from "@ngrx/effects/testing"
 import { Action } from "@ngrx/store"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { hot } from "jasmine-marbles"
-import { NEVER, ReplaySubject, of, throwError } from "rxjs"
+import { EMPTY, NEVER, ReplaySubject, of, throwError } from "rxjs"
 import { SAPI, SAPIModule } from "src/atlasComponents/sapi"
 import { SxplrRegion, SxplrAtlas, SxplrParcellation, SxplrTemplate } from "src/atlasComponents/sapi/sxplrTypes"
 import { IDS } from "src/atlasComponents/sapi/constants"
@@ -15,6 +15,7 @@ import { BrowserAnimationsModule } from "@angular/platform-browser/animations"
 import { translateV3Entities } from "src/atlasComponents/sapi/translateV3"
 import { PathReturn } from "src/atlasComponents/sapi/typeV3"
 import { MatDialog } from 'src/sharedModules/angularMaterial.exports'
+import { InterSpaceCoordXformSvc } from "src/atlasComponents/sapi/core/space/interSpaceCoordXform.service"
 
 describe("> effects.ts", () => {
   describe("> Effect", () => {
@@ -104,6 +105,14 @@ describe("> effects.ts", () => {
               }
             }
           },
+          {
+            provide: InterSpaceCoordXformSvc,
+            useValue: {
+              transform() {
+                return EMPTY
+              }
+            }
+          }
         ]
       })
     })
diff --git a/src/util/constants.ts b/src/util/constants.ts
index b2a3735ee186204935f11e1fdb8492dd7daa0c3d..b1411dc432430330bffc9d552cc486dc2a3c95bb 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -101,3 +101,7 @@ export const parcBanList: string[] = [
   "minds/core/parcellationatlas/v1.0.0/887da8eb4c36d944ef626ed5293db3ef",
   "minds/core/parcellationatlas/v1.0.0/f2b1ac621421708c1bef422bb5058456",
 ]
+
+export const GET_ATTR_TOKEN = new InjectionToken("GET_ATTR_TOKEN")
+
+export type GetAttr = (attr: string) => string|null
\ No newline at end of file