diff --git a/NodeApp/src/managers/DojoBackendManager.ts b/NodeApp/src/managers/DojoBackendManager.ts
index 0a878367581dbd7022567590557cf88222c05d00..0317027ac5b3c14cc07dc4b1486c310734657aad 100644
--- a/NodeApp/src/managers/DojoBackendManager.ts
+++ b/NodeApp/src/managers/DojoBackendManager.ts
@@ -1,7 +1,6 @@
 import axios, { AxiosError } from 'axios';
 import ora                   from 'ora';
 import ApiRoute              from '../sharedByClients/types/Dojo/ApiRoute.js';
-import ClientsSharedConfig   from '../sharedByClients/config/ClientsSharedConfig.js';
 import Assignment            from '../sharedByClients/models/Assignment.js';
 import DojoBackendResponse   from '../shared/types/Dojo/DojoBackendResponse.js';
 import Exercise              from '../sharedByClients/models/Exercise.js';
@@ -14,10 +13,121 @@ import GitlabPipelineStatus  from '../shared/types/Gitlab/GitlabPipelineStatus.j
 import Tag                   from '../sharedByClients/models/Tag';
 import TagProposal           from '../sharedByClients/models/TagProposal';
 import Result                from '../sharedByClients/models/Result';
+import ClientsSharedConfig   from '../sharedByClients/config/ClientsSharedConfig';
+import inquirer              from 'inquirer';
+import SharedConfig          from '../shared/config/SharedConfig';
+import ConfigFiles           from '../config/ConfigFiles';
 
 
 class DojoBackendManager {
-    private handleApiError(error: unknown, spinner: ora.Ora, verbose: boolean, defaultErrorMessage?: string, otherErrorHandler?: (error: AxiosError, spinner: ora.Ora, verbose: boolean) => void) {
+    readonly API_URL_CONFIG_KEY = 'apiUrl';
+
+    public async getApiUrl(): Promise<string> {
+        //Read the config file to get the api url. If there is no api url, then ask the user to provide one.
+        return ConfigFiles.stateConfigFile.getParam(this.API_URL_CONFIG_KEY) as string | null || await this.askApiUrl();
+    }
+
+    public async cleanApiUrl(): Promise<void> {
+        const cleanApiSpinner: ora.Ora = ora('Cleaning Api URL...').start();
+        ConfigFiles.stateConfigFile.setParam(this.API_URL_CONFIG_KEY, null);
+        cleanApiSpinner.succeed('API URL successfully cleaned');
+    }
+
+    /**
+     * Check if the given api url is valid and save it in the config file if it is.
+     * @param apiUrl
+     * @returns {Promise<boolean>} true if the api url is valid, false otherwise
+     */
+    public async setApiUrl(apiUrl: string): Promise<boolean> {
+        let isApiUrlValid: boolean = false;
+
+        const testApiSpinner: ora.Ora = ora('Testing Api URL...').start();
+        try {
+            isApiUrlValid = (await axios.get<DojoBackendResponse<unknown>>(`${ apiUrl }${ ApiRoute.CLIENTS_CONFIG }`)).status === 200;
+        } catch ( e ) {
+            isApiUrlValid = false;
+        }
+
+        if ( isApiUrlValid ) {
+            // End step: Store the preference in the config file
+            ConfigFiles.stateConfigFile.setParam(this.API_URL_CONFIG_KEY, apiUrl);
+        }
+
+        isApiUrlValid ? testApiSpinner.succeed('API URL successfully saved') : testApiSpinner.fail('The API URL is invalid');
+
+        return isApiUrlValid;
+    }
+
+    public async askApiUrl(showClean: boolean = false): Promise<string> {
+        const presets: Array<{ name: string, value: string } | inquirer.Separator> = [ {
+            name : 'HEPIA',
+            value: 'https://rdps.hesge.ch/dojo/api'
+        }, {
+            name : 'Other',
+            value: 'other'
+        } ];
+
+        if ( !SharedConfig.production ) {
+            presets.unshift({
+                                name : 'DEV',
+                                value: 'http://localhost:30993'
+                            }, {
+                                name : 'TEST',
+                                value: 'http://dojo-test.edu.hesge.ch/dojo/api'
+                            }, new inquirer.Separator());
+        }
+
+        if ( showClean ) {
+            presets.push(new inquirer.Separator(), {
+                name : 'Clean API settings',
+                value: 'clean'
+            });
+        }
+
+        presets.push(new inquirer.Separator(), {
+            name : 'Quit',
+            value: 'quit'
+        });
+
+        let apiUrl: string = '';
+        let isApiUrlValid: boolean = false;
+
+        do {
+            // First step: Propose some presets with inquirer
+            apiUrl = (await inquirer.prompt({
+                                                name    : 'apiUrl',
+                                                message : 'Which API do you want to use?',
+                                                type    : 'list',
+                                                pageSize: 1000,
+                                                choices : presets,
+                                                default : SharedConfig.production ? 'other' : 'http://localhost:30993'
+                                            })).apiUrl;
+
+
+            // Second step: If the user chooses other, then ask for the url of the api
+            switch ( apiUrl ) {
+                case 'other':
+                    apiUrl = (await inquirer.prompt({
+                                                        name   : 'apiUrl',
+                                                        message: 'Please provide the URL of the API',
+                                                        type   : 'input'
+                                                    })).apiUrl;
+                    break;
+                case 'clean':
+                    await this.cleanApiUrl();
+                    return '';
+                case 'quit':
+                    process.exit(0);
+            }
+
+            // Third step: Test the api url
+            isApiUrlValid = await this.setApiUrl(apiUrl);
+        } while ( !isApiUrlValid );
+
+        return apiUrl;
+    }
+
+    private async handleApiError(error: unknown, spinner: ora.Ora, verbose: boolean, defaultErrorMessage?: string, otherErrorHandler?: (error: AxiosError, spinner: ora.Ora, verbose: boolean) => void) {
         const unknownErrorMessage: string = 'unknown error';
 
         if ( verbose ) {
@@ -129,7 +239,7 @@ class DojoBackendManager {
 
             return true;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Template error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Template error: ${ error }`);
 
             return false;
         }
@@ -154,7 +264,7 @@ class DojoBackendManager {
 
             return response.data.data;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Assignment creation error: unknown error`);
+            await this.handleApiError(error, spinner, verbose, `Assignment creation error: unknown error`);
 
             throw error;
         }
@@ -176,7 +286,7 @@ class DojoBackendManager {
 
             return response.data.data;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Exercise creation error: unknown error`);
+            await this.handleApiError(error, spinner, verbose, `Exercise creation error: unknown error`);
 
             throw error;
         }
@@ -198,7 +308,7 @@ class DojoBackendManager {
 
             return;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Assignment visibility change error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Assignment visibility change error: ${ error }`);
 
             throw error;
         }
@@ -230,7 +340,7 @@ class DojoBackendManager {
 
             return true;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Correction ${ isUpdate ? 'update' : 'link' } error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Correction ${ isUpdate ? 'update' : 'link' } error: ${ error }`);
 
             return false;
         }
@@ -255,7 +365,7 @@ class DojoBackendManager {
 
             return true;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Correction unlink error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Correction unlink error: ${ error }`);
 
             return false;
         }
@@ -280,7 +390,7 @@ class DojoBackendManager {
 
             return response.data.data;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Tag creation error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Tag creation error: ${ error }`);
 
             return undefined;
         }
@@ -302,7 +412,7 @@ class DojoBackendManager {
 
             return true;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Tag deletion error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Tag deletion error: ${ error }`);
 
             return false;
         }
@@ -335,7 +445,7 @@ class DojoBackendManager {
 
             return response.data.data;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Tag proposal creation error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Tag proposal creation error: ${ error }`);
 
             return undefined;
         }
@@ -360,7 +470,7 @@ class DojoBackendManager {
 
             return true;
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Tag proposal answer error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Tag proposal answer error: ${ error }`);
 
             return false;
         }
@@ -405,7 +515,7 @@ class DojoBackendManager {
                 spinner.succeed(`Exercise deleted with success`);
             }
         } catch ( error ) {
-            this.handleApiError(error, spinner, verbose, `Exercise deleting error: ${ error }`);
+            await this.handleApiError(error, spinner, verbose, `Exercise deleting error: ${ error }`);
 
             throw error;
         }