diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4d31798be711a9682bd5363bf7187fd644973ea7..47df1bb53233eb8ff5c3a70cebe7c9425c2eeb59 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -37,6 +37,11 @@ jobs:
         node-version: 16.x
     - run: npm i
     - run: |
+        if [[ "$GITHUB_REF" = *hotfix* ]] || [[ "$GITHUB_REF" = refs/heads/staging ]]
+        then
+          export SIIBRA_API_ENDPOINTS=https://siibra-api-rc.apps.hbp.eu/v2_0
+          node src/environments/parseEnv.js ./environment.common.ts
+        fi
         npm run test-ci
 
   backend:
diff --git a/src/atlasComponents/sapi/features/sapiFeature.ts b/src/atlasComponents/sapi/features/sapiFeature.ts
index 5abaa0040f6cb71046c70bf57e7a77a57f2794a8..8290da0cad9b4c8e057845258980ff5091579272 100644
--- a/src/atlasComponents/sapi/features/sapiFeature.ts
+++ b/src/atlasComponents/sapi/features/sapiFeature.ts
@@ -7,7 +7,7 @@ export class SAPIFeature {
   }
 
   public detail$ = this.sapi.httpGet<SapiFeatureModel>(
-    `${SAPI.bsEndpoint}/features/${this.id}`,
+    `${SAPI.BsEndpoint}/features/${this.id}`,
     this.opts
   )
 }
diff --git a/src/atlasComponents/sapi/sapi.service.spec.ts b/src/atlasComponents/sapi/sapi.service.spec.ts
index 297105f3fc148a1b6a1f3fb01f39d88ec0983cfb..0448de0ccf6c7c2fcb3d5cd587e996db861a7bf2 100644
--- a/src/atlasComponents/sapi/sapi.service.spec.ts
+++ b/src/atlasComponents/sapi/sapi.service.spec.ts
@@ -1,3 +1,4 @@
+import { NEVER } from "rxjs"
 import * as env from "src/environments/environment"
 import { SAPI } from "./sapi.service"
 
@@ -7,16 +8,24 @@ describe("> sapi.service.ts", () => {
       let fetchSpy: jasmine.Spy
       let environmentSpy: jasmine.Spy
 
-      const endpt1 = 'foo-bar'
-      const endpt2 = 'buzz-bizz'
+      const endpt1 = 'http://foo-bar'
+      const endpt2 = 'http://buzz-bizz'
 
       const atlas1 = 'foo'
       const atlas2 = 'bar'
-      
 
+      let originalBsEndpoint: string
+      beforeAll(() => {
+        originalBsEndpoint = SAPI.BsEndpoint
+      })
+
+      afterAll(() => {
+        SAPI.BsEndpoint = originalBsEndpoint
+      })
+      
       beforeEach(() => {
         fetchSpy = spyOn(window, 'fetch')
-        fetchSpy.and.rejectWith("foo-bar")
+        fetchSpy.and.callThrough()
 
         environmentSpy = spyOnProperty(env, 'environment')
         environmentSpy.and.returnValue({
@@ -42,7 +51,7 @@ describe("> sapi.service.ts", () => {
 
         it("> endpoint should be set", async () => {
           await SAPI.SetBsEndPoint()
-          expect(SAPI.bsEndpoint).toBe(endpt1)
+          expect(SAPI.BsEndpoint).toBe(endpt1)
         })
       })
 
@@ -70,7 +79,17 @@ describe("> sapi.service.ts", () => {
 
         it('> should set endpt2', async () => {
           await SAPI.SetBsEndPoint()
-          expect(SAPI.bsEndpoint).toBe(endpt2)
+          expect(SAPI.BsEndpoint).toBe(endpt2)
+        })
+
+        it("> instances bsendpoint should be the updated version", async () => {
+          await SAPI.SetBsEndPoint()
+          const mockHttpClient = {
+            get: jasmine.createSpy()
+          }
+          mockHttpClient.get.and.returnValue(NEVER)
+          const sapi = new SAPI(mockHttpClient as any, null, null)
+          expect(sapi.bsEndpoint).toBe(endpt2)
         })
       })
     })
diff --git a/src/atlasComponents/sapi/sapi.service.ts b/src/atlasComponents/sapi/sapi.service.ts
index a3b20176f9aabd68c948d811c6582178d7b2a261..394acc033c64d0b3567024c4f65f1ddc53dfc3c1 100644
--- a/src/atlasComponents/sapi/sapi.service.ts
+++ b/src/atlasComponents/sapi/sapi.service.ts
@@ -41,7 +41,7 @@ export class SAPI{
         const resp = await fetch(`${url}/atlases`)
         const atlases = await resp.json()
         if (atlases.length > 0) {
-          SAPI.bsEndpoint = url
+          SAPI.BsEndpoint = url
           return
         }
       } catch (e) {
@@ -52,8 +52,11 @@ export class SAPI{
   }
 
   static ErrorMessage = null
-  static bsEndpoint = `https://siibra-api-stable.apps.hbp.eu/v2_0`
-  public bsEndpoint = SAPI.bsEndpoint
+  static BsEndpoint = `https://siibra-api-rc.apps.hbp.eu/v2_0`
+
+  get bsEndpoint() {
+    return SAPI.BsEndpoint
+  }
   
   registry = {
     _map: {} as Record<string, {
@@ -113,7 +116,7 @@ export class SAPI{
   }
 
   getModalities(): Observable<SapiModalityModel[]> {
-    return this.http.get<SapiModalityModel[]>(`${SAPI.bsEndpoint}/modalities`)
+    return this.http.get<SapiModalityModel[]>(`${SAPI.BsEndpoint}/modalities`)
   }
 
   httpGet<T>(url: string, params?: Record<string, string>, sapiParam?: SapiQueryPriorityArg){
diff --git a/src/atlasComponents/sapi/stories.base.ts b/src/atlasComponents/sapi/stories.base.ts
index 51fde4f0cd5695f6055398e8bd9ec39ed469c541..1fa58bef89b562d5be3ad8ef5383c302bb335649 100644
--- a/src/atlasComponents/sapi/stories.base.ts
+++ b/src/atlasComponents/sapi/stories.base.ts
@@ -67,22 +67,22 @@ export const parcId = {
 }
 
 export async function getAtlases(): Promise<SapiAtlasModel[]> {
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases`)).json() as SapiAtlasModel[]
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases`)).json() as SapiAtlasModel[]
 }
 
 export async function getAtlas(id: string): Promise<SapiAtlasModel>{
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${id}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${id}`)).json()
 }
 
 export async function getParc(atlasId: string, id: string): Promise<SapiParcellationModel>{
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/parcellations/${id}`)).json()
 }
 export async function getParcRegions(atlasId: string, id: string, spaceId: string): Promise<SapiRegionModel[]>{
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}/regions?space_id=${encodeURIComponent(spaceId)}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/parcellations/${id}/regions?space_id=${encodeURIComponent(spaceId)}`)).json()
 }
 
 export async function getSpace(atlasId: string, id: string): Promise<SapiSpaceModel> {
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/spaces/${id}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId}/spaces/${id}`)).json()
 }
 
 export async function getHumanAtlas(): Promise<SapiAtlasModel> {
@@ -90,7 +90,7 @@ export async function getHumanAtlas(): Promise<SapiAtlasModel> {
 }
 
 export async function getMni152(): Promise<SapiSpaceModel> {
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}`)).json()
 }
 
 export async function getJba29(): Promise<SapiParcellationModel> {
@@ -103,33 +103,33 @@ export async function getJba29Regions(): Promise<SapiRegionModel[]> {
 
 export async function getHoc1Right(spaceId=null): Promise<SapiRegionModel> {
   if (!spaceId) {
-    return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right`)).json()
+    return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right`)).json()
   }
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right?space_id=${encodeURIComponent(spaceId)}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right?space_id=${encodeURIComponent(spaceId)}`)).json()
 }
 
 export async function get44Left(spaceId=null): Promise<SapiRegionModel> {
   if (!spaceId) {
-    return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left`)).json()
+    return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left`)).json()
   }
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left?space_id=${encodeURIComponent(spaceId)}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left?space_id=${encodeURIComponent(spaceId)}`)).json()
 }
 
 export async function getHoc1RightSpatialFeatures(): Promise<SxplrCleanedFeatureModel[]> {
-  const json: SapiSpatialFeatureModel[] = await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features?parcellation_id=2.9&region=hoc1%20right`)).json()
+  const json: SapiSpatialFeatureModel[] = await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features?parcellation_id=2.9&region=hoc1%20right`)).json()
   return cleanIeegSessionDatasets(json.filter(it => it['@type'] === "siibra/features/ieegSession"))
 }
 
 export async function getHoc1RightFeatures(): Promise<SapiRegionalFeatureModel[]> {
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features`)).json()
 }
 
 export async function getHoc1RightFeatureDetail(featId: string): Promise<SapiRegionalFeatureModel>{
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features/${encodeURIComponent(featId)}`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20right/features/${encodeURIComponent(featId)}`)).json()
 }
 
 export async function getJba29Features(): Promise<SapiParcellationFeatureModel[]> {
-  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/features`)).json()
+  return await (await fetch(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/features`)).json()
 }
 
 export async function getBigbrainSpatialFeatures(): Promise<SapiSpatialFeatureModel[]>{
@@ -137,14 +137,14 @@ export async function getBigbrainSpatialFeatures(): Promise<SapiSpatialFeatureMo
     [-1000, -1000, -1000],
     [1000, 1000, 1000]
   ]
-  const url = new URL(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.bigbrain}/features`)
+  const url = new URL(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.bigbrain}/features`)
   url.searchParams.set(`bbox`, JSON.stringify(bbox))
   return await (await fetch(url.toString())).json()
 }
 
 export async function getMni152SpatialFeatureHoc1Right(): Promise<SapiSpatialFeatureModel[]>{
   
-  const url = new URL(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features`)
+  const url = new URL(`${SAPI.BsEndpoint}/atlases/${atlasId.human}/spaces/${spaceId.human.mni152}/features`)
   url.searchParams.set(`parcellation_id`, parcId.human.jba29)
   url.searchParams.set("region", 'hoc1 right')
   return await (await fetch(url.toString())).json()
diff --git a/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts
index 77df043bb37ed7ffb87cad72d422dda777db33d0..972e411795a3ac9e3a862a3cb61bc7d403f1a105 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.spec.ts
@@ -3,11 +3,11 @@ import { SAPI } from "src/atlasComponents/sapi/sapi.service"
 import { SapiParcellationModel } from "src/atlasComponents/sapi/type"
 import { getTraverseFunctions } from "./parcellationVersion.pipe"
 
-describe(`parcellationVersion.pipe.ts (endpoint at ${SAPI.bsEndpoint})`, () => {
+describe(`parcellationVersion.pipe.ts (endpoint at ${SAPI.BsEndpoint})`, () => {
   describe("getTraverseFunctions", () => {
     let julichBrainParcellations: SapiParcellationModel[] = []
     beforeAll(async () => {
-      const res = await fetch(`${SAPI.bsEndpoint}/atlases/${encodeURIComponent(IDS.ATLAES.HUMAN)}/parcellations`)
+      const res = await fetch(`${SAPI.BsEndpoint}/atlases/${encodeURIComponent(IDS.ATLAES.HUMAN)}/parcellations`)
       const arr: SapiParcellationModel[] = await res.json()
       julichBrainParcellations = arr.filter(it => /Julich-Brain Cytoarchitectonic Maps/.test(it.name))
     })
diff --git a/src/environments/parseEnv.js b/src/environments/parseEnv.js
index 7b23070ca889aae07002b73c51f1549050fa369c..9533d341158797f5da8a604929d9327e8980545f 100644
--- a/src/environments/parseEnv.js
+++ b/src/environments/parseEnv.js
@@ -2,9 +2,11 @@ const fs = require('fs')
 const path = require('path')
 const { promisify } = require('util')
 const asyncWrite = promisify(fs.writeFile)
+const process = require("process")
 
 const main = async () => {
-  const pathToEnvFile = path.join(__dirname, './environment.prod.ts')
+  const target = process.argv[2] || './environment.prod.ts'
+  const pathToEnvFile = path.join(__dirname, target)
   const {
     BACKEND_URL,
     STRICT_LOCAL,
diff --git a/src/share/saneUrl/saneUrl.component.spec.ts b/src/share/saneUrl/saneUrl.component.spec.ts
index 5ab173950c92148144b7b3025f63cddf95205a30..982ecb76fb47ca954a5da6c9f5c792c69f3118ba 100644
--- a/src/share/saneUrl/saneUrl.component.spec.ts
+++ b/src/share/saneUrl/saneUrl.component.spec.ts
@@ -1,14 +1,13 @@
-import { TestBed, fakeAsync, tick, flush } from '@angular/core/testing'
-import { ShareModule } from '../share.module'
+import { TestBed, fakeAsync, tick, flush, ComponentFixture } from '@angular/core/testing'
 import { SaneUrl } from './saneUrl.component'
-import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'
 import { By } from '@angular/platform-browser'
 import { BACKENDURL } from 'src/util/constants'
 import { NoopAnimationsModule } from '@angular/platform-browser/animations'
 import { SaneUrlSvc } from './saneUrl.service'
 import { AngularMaterialModule } from 'src/sharedModules'
 import { CUSTOM_ELEMENTS_SCHEMA, Directive } from '@angular/core'
-import { of } from 'rxjs'
+import { of, throwError } from 'rxjs'
+import { NotFoundError } from '../type'
 
 const inputCss = `input[aria-label="Custom link"]`
 const submitCss = `button[aria-label="Create custom link"]`
@@ -25,15 +24,22 @@ class AuthStateDummy {
 
 describe('> saneUrl.component.ts', () => {
   describe('> SaneUrl', () => {
+    const mockSaneUrlSvc = {
+      saneUrlroot: 'saneUrlroot',
+      getKeyVal: jasmine.createSpy('getKeyVal'),
+      setKeyVal: jasmine.createSpy('setKeyVal'),
+    }
     beforeEach(async () => {
       await TestBed.configureTestingModule({
         imports: [
-          HttpClientTestingModule,
           NoopAnimationsModule,
           AngularMaterialModule,
         ],
         providers: [
-          SaneUrlSvc,
+          {
+            provide: SaneUrlSvc,
+            useValue: mockSaneUrlSvc
+          }
         ],
         declarations: [
           SaneUrl,
@@ -43,11 +49,18 @@ describe('> saneUrl.component.ts', () => {
           CUSTOM_ELEMENTS_SCHEMA
         ]
       }).compileComponents()
+
+      mockSaneUrlSvc.getKeyVal.and.returnValue(
+        of('foo-bar')
+      )
+      mockSaneUrlSvc.setKeyVal.and.returnValue(
+        of('OK')
+      )
     })
 
     afterEach(() => {
-      const ctrl = TestBed.inject(HttpTestingController)
-      ctrl.verify()
+      mockSaneUrlSvc.getKeyVal.calls.reset()
+      mockSaneUrlSvc.setKeyVal.calls.reset()
     })
 
     it('> can be created', () => {
@@ -112,215 +125,188 @@ describe('> saneUrl.component.ts', () => {
       const input = fixture.debugElement.query( By.css( inputCss ) )
     })
 
-    it('> on entering string in input, makes debounced GET request', fakeAsync(() => {
-
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush(200)
-    }))
-
-    it('> on 200 response, show error', fakeAsync(() => {
-      
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush('OK')
-
-      // Expect validator to fail catch it
-      expect(fixture.componentInstance.customUrl.invalid).toEqual(true)
-
-      // on change detection, UI should catch it
-      fixture.detectChanges()
-
-      const input = fixture.debugElement.query( By.css( inputCss ) )
-
-      const submit = fixture.debugElement.query( By.css( submitCss ) )
-      const disabled = !!submit.attributes['disabled']
-      expect(disabled.toString()).toEqual('true')
-    }))
-
-    it('> on 404 response, show available', fakeAsync(() => {
-
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush('some reason', { status: 404, statusText: 'Not Found.' })
-
-      // Expect validator to fail catch it
-      expect(fixture.componentInstance.customUrl.invalid).toEqual(false)
-
-      // on change detection, UI should catch it
-      fixture.detectChanges()
-
-      const input = fixture.debugElement.query( By.css( inputCss ) )
-
-      const submit = fixture.debugElement.query( By.css( submitCss ) )
-      const disabled = !!submit.attributes['disabled']
-      expect(disabled.toString()).toEqual('false')
-    }))
-
-    it('> on other error codes, show invalid', fakeAsync(() => {
-
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush('some reason', { status: 401, statusText: 'Unauthorised.' })
-
-      // Expect validator to fail catch it
-      expect(fixture.componentInstance.customUrl.invalid).toEqual(true)
-
-      // on change detection, UI should catch it
-      fixture.detectChanges()
-
-      const input = fixture.debugElement.query( By.css( inputCss ) )
-
-      const submit = fixture.debugElement.query( By.css( submitCss ) )
-      const disabled = !!submit.attributes['disabled']
-      expect(disabled.toString()).toEqual('true')
-    }))
-
-    it('> on click create link btn calls correct API', fakeAsync(() => {
-
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush('some reason', { status: 404, statusText: 'Not Found.' })
-
-      fixture.detectChanges()
-      flush()
-
-      const submit = fixture.debugElement.query( By.css( submitCss ) )
-      const disabled = !!submit.attributes['disabled']
-      expect(disabled.toString()).toEqual('false')
-
-      submit.triggerEventHandler('click', {})
-
-      fixture.detectChanges()
-
-      const disabledInProgress = !!submit.attributes['disabled']
-      expect(disabledInProgress.toString()).toEqual('true')
-
-      const req2 = httpTestingController.expectOne({
-        method: 'POST',
-        url: `${BACKENDURL}saneUrl/${value}`
+    describe("> on valid input", () => {
+      let saneUrlCmp: SaneUrl
+      let fixture: ComponentFixture<SaneUrl>
+      const stateTobeSaved = 'foo-bar'
+      beforeEach(() => {
+        // Necessary to detectChanges, or formControl will not initialise properly
+        // See https://stackoverflow.com/a/56600762/6059235
+        fixture = TestBed.createComponent(SaneUrl)
+        saneUrlCmp = fixture.componentInstance
+        saneUrlCmp.stateTobeSaved = stateTobeSaved
+        fixture.detectChanges()
       })
-      
-      req2.flush({})
-
-      fixture.detectChanges()
-
-      const disabledAfterComplete = !!submit.attributes['disabled']
-      expect(disabledAfterComplete.toString()).toEqual('true')
-
-      const cpyBtn = fixture.debugElement.query( By.css( copyBtnCss ) )
-      expect(cpyBtn).toBeTruthy()
-    }))
-
-    it('> on click create link btn fails show result', fakeAsync(() => {
-
-      const value = 'test_1'
-
-      const httpTestingController = TestBed.inject(HttpTestingController)
-
-      // Necessary to detectChanges, or formControl will not initialise properly
-      // See https://stackoverflow.com/a/56600762/6059235
-      const fixture = TestBed.createComponent(SaneUrl)
-      fixture.detectChanges()
-
-      // Set value
-      fixture.componentInstance.customUrl.setValue(value)
-
-      tick(500)
-
-      const req = httpTestingController.expectOne(`${BACKENDURL}saneUrl/${value}`)
-      req.flush('some reason', { status: 404, statusText: 'Not Found.' })
-
-      fixture.detectChanges()
-      flush()
-
-      const submit = fixture.debugElement.query( By.css( submitCss ) )
-      const disabled = !!submit.attributes['disabled']
-      expect(disabled.toString()).toEqual('false')
-
-      submit.triggerEventHandler('click', {})
-
-      fixture.detectChanges()
-
-      const disabledInProgress = !!submit.attributes['disabled']
-      expect(disabledInProgress.toString()).toEqual('true')
-
-      const req2 = httpTestingController.expectOne({
-        method: 'POST',
-        url: `${BACKENDURL}saneUrl/${value}`
+      it('> on entering string in input, makes debounced GET request', fakeAsync(() => {
+
+        const value = 'test_1'
+  
+        // Set value
+        fixture.componentInstance.customUrl.setValue(value)
+  
+        tick(500)
+  
+        expect(mockSaneUrlSvc.getKeyVal).toHaveBeenCalledOnceWith(value)
+      }))
+  
+      describe("> on 200", () => {
+        it("> show error", fakeAsync(() => {
+  
+          const value = 'test_1'
+    
+          // Set value
+          fixture.componentInstance.customUrl.setValue(value)
+    
+          tick(500)
+    
+          // Expect validator to fail catch it
+          expect(fixture.componentInstance.customUrl.invalid).toEqual(true)
+    
+          // on change detection, UI should catch it
+          fixture.detectChanges()
+    
+          const input = fixture.debugElement.query( By.css( inputCss ) )
+    
+          const submit = fixture.debugElement.query( By.css( submitCss ) )
+          const disabled = !!submit.attributes['disabled']
+          expect(disabled.toString()).toEqual('true')
+        }))
+      })
+  
+      describe('> on 404', () => {
+        beforeEach(() => {
+          mockSaneUrlSvc.getKeyVal.and.returnValue(
+            throwError(new NotFoundError('not found'))
+          )
+        })
+        it("> should available", fakeAsync(() => {
+  
+          const value = 'test_1'
+    
+          // Set value
+          fixture.componentInstance.customUrl.setValue(value)
+    
+          tick(500)
+    
+          // Expect validator to fail catch it
+          expect(fixture.componentInstance.customUrl.invalid).toEqual(false)
+    
+          // on change detection, UI should catch it
+          fixture.detectChanges()
+    
+          const input = fixture.debugElement.query( By.css( inputCss ) )
+    
+          const submit = fixture.debugElement.query( By.css( submitCss ) )
+          const disabled = !!submit.attributes['disabled']
+          expect(disabled.toString()).toEqual('false')
+        }))
       })
+  
+      describe("> on other error", () => {
+        beforeEach(() => {
+  
+          mockSaneUrlSvc.getKeyVal.and.returnValue(
+            throwError(new Error('other errors'))
+          )
+        })
+        it("> show invalid", fakeAsync(() => {
+          const value = 'test_1'
+    
+          // Set value
+          fixture.componentInstance.customUrl.setValue(value)
+    
+          tick(500)
+    
+          // Expect validator to fail catch it
+          expect(fixture.componentInstance.customUrl.invalid).toEqual(true)
+    
+          // on change detection, UI should catch it
+          fixture.detectChanges()
+    
+          const input = fixture.debugElement.query( By.css( inputCss ) )
+    
+          const submit = fixture.debugElement.query( By.css( submitCss ) )
+          const disabled = !!submit.attributes['disabled']
+          expect(disabled.toString()).toEqual('true')
+        }))
+      })
+  
+      describe("> on click create link", () => {
+        beforeEach(() => {
+          mockSaneUrlSvc.getKeyVal.and.returnValue(
+            throwError(new NotFoundError('not found'))
+          )
+        })
+        it("> calls correct service function", fakeAsync(() => {
+  
+          const value = 'test_1'
+    
+          // Set value
+          fixture.componentInstance.customUrl.setValue(value)
+    
+          tick(500)
+    
+          fixture.detectChanges()
+          flush()
+    
+          const submit = fixture.debugElement.query( By.css( submitCss ) )
+          const disabled = !!submit.attributes['disabled']
+          expect(disabled.toString()).toEqual('false')
+    
+          submit.triggerEventHandler('click', {})
+    
+          fixture.detectChanges()
+    
+          const disabledInProgress = !!submit.attributes['disabled']
+          expect(disabledInProgress.toString()).toEqual('true')
+    
+          fixture.detectChanges()
+    
+          const disabledAfterComplete = !!submit.attributes['disabled']
+          expect(disabledAfterComplete.toString()).toEqual('true')
+    
+          const cpyBtn = fixture.debugElement.query( By.css( copyBtnCss ) )
+          expect(cpyBtn).toBeTruthy()
+        }))
+  
+        describe("> on fail", () => {
+          beforeEach(() => {
+            mockSaneUrlSvc.setKeyVal.and.returnValue(
+              throwError(new Error(`some error`))
+            )
+          })
+          it("> show result", fakeAsync(() => {
+  
+            const value = 'test_1'
       
-      req2.flush('Something went wrong', { statusText: 'Wrong status text', status: 500 })
-
-      fixture.detectChanges()
-
-      const input = fixture.debugElement.query( By.css( inputCss ) )
-
-    }))
+            // Set value
+            fixture.componentInstance.customUrl.setValue(value)
+      
+            tick(500)
+      
+            fixture.detectChanges()
+      
+            const submit = fixture.debugElement.query( By.css( submitCss ) )
+            const disabled = !!submit.attributes['disabled']
+            expect(disabled.toString()).toEqual('false')
+      
+            submit.triggerEventHandler('click', {})
+      
+            fixture.detectChanges()
+      
+            const disabledInProgress = !!submit.attributes['disabled']
+            expect(disabledInProgress.toString()).toEqual('true')
+      
+            expect(mockSaneUrlSvc.setKeyVal).toHaveBeenCalledOnceWith(value, stateTobeSaved)
+            
+            fixture.detectChanges()
+      
+            const input = fixture.debugElement.query( By.css( inputCss ) )
+      
+          }))
+        })
+      })
+  
+    })
   })
 })
diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
index ce0afa8fa8632b433b5998eed1107654fdc4dfa2..ab6ac511153553a1bc50365bd2b85c4a239c94f4 100644
--- a/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
+++ b/src/viewerModule/nehuba/statusCard/statusCard.component.spec.ts
@@ -146,8 +146,8 @@ describe('> statusCard.component.ts', () => {
           initialNgState: {
             navigation: {
               pose: {
-                orientation: [0,0,0,1],
-                position: [10, 20, 30]
+                orientation: [0, 0, 0, 1],
+                position: [0, 0, 0]
               },
               zoomFactor: 1e6
             }