diff --git a/config/engine.yaml b/config/engine.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8924a38c76c16231a55e955881eb13f8da26cb80
--- /dev/null
+++ b/config/engine.yaml
@@ -0,0 +1,129 @@
+##############################################
+#            Engine Configuration            #
+##############################################
+
+general:
+  log:
+    # Directory where the log file resides
+    directory: logs
+    # Possible values: debug, info, warning, error, critical
+    level: info
+
+  # Path to the engine-core socket directory relative to the engine project root
+  socket_dir: ../engine-core/socket
+  # Directory to store temporary data
+  cache_dir: ./.cache
+
+  # Details for the Station Fallback
+  fallback:
+    show_name: Random Music
+    show_id: -1
+
+monitoring:
+  mail:
+    # Mail server credentials for sending email notifications (Admin and Programme Coordination)
+    host: mail.your-radio.org
+    port: 587
+    user: aura@subsquare.at
+    pwd: ---SECRET--PASSWORD---
+
+    coordinator:
+      # Set to "true" if you want to notify programme-coordinators about about fallback situations, otherwise "false"
+      enabled: false
+      # If you want to address multiple programme-coordinators separate their emails by space
+      mail: programme-coordinator@your-radio.org
+
+    admin:
+      # Set to "true" if you want to notify admins about incidents, otherwise "false"
+      enabled: false
+      # If you want to address multiple administrators separate their emails by space
+      mail: david@subsquare.at
+
+    # The FROM email address used when sending
+    from: monitoring@aura.engine
+    # A subject prefix allows applying filter rules in your mail client
+    subject_prefix: "[AURA Engine]" # default: [AURA Engine]
+
+  heartbeat:
+    # Seconds how often the vitality of Engine Core should be checked (default: 1)
+    frequency: 1
+    # Host where heartbeat is sent to (disabled if empty string)
+    host: ""
+    # Some UDP port
+    port: 43334
+
+api:
+  ## STEERING ##
+  steering:
+    # The URL to get the health status
+    status: http://localhost:8000/api/v1/
+    # The URL to get the Calendar via Steering
+    calendar: http://localhost:8000/api/v1/playout
+
+  ## TANK ##
+  tank:
+    # The session name which is used to authenticate against Tank
+    session: engine
+    # The secret which is used to authenticate against Tank
+    secret: rather-secret
+    # The URL to get the health status
+    status: http://localhost:8040/healthz
+    # The URL to get playlist details via Tank
+    playlist: http://localhost:8040/api/v1/playlists/${ID}
+
+  ## ENGINE-API ##
+  engine:
+    # Engine ID (1 or 2)
+    number: 1
+    # Engine API availability check
+    status: http://localhost:8008/api/v1/ui/
+    # Engine API endpoint to store playlogs
+    store_playlog: http://localhost:8008/api/v1/playlog
+    # Engine API endpoint to store clock information
+    store_clock: http://localhost:8008/api/v1/clock
+    # Engine API endpoint to store health information
+    store_health: http://localhost:8008/api/v1/source/health/${ENGINE_NUMBER}
+
+scheduler:
+  # Database settings: Use 'postgresql', 'sqlite' or 'mysql'. In case of SQLite the "db_name" is the name of the file.
+  db:
+    type: sqlite
+    name: aura_engine
+    user: aura_engine
+    pwd: ---SECRET--PASSWORD---
+    host: localhost
+    charset: utf8
+    
+  # Base path as seen by "engine-core", not accessed by "engine"; this is required to construct the absolute audio file path (check "Audio Store" in the docs)
+  # Either provide an absolute base path or a relative one starting in the `engine` directory. In case of `engine-core` running in docker use `/var/audio/source`
+  audio:
+    source_folder: ../engine-core/audio/source
+    source_extension: .flac
+    # Folder holding M3U Playlists to be scheduled in form of Engine Playlists (similar as audio source folder above)
+    playlist_folder: ../engine-core/audio/playlist
+    # Offset in seconds how long it takes for Liquidsoap to actually execute a scheduler command; Crucial to keep things in sync
+    engine_latency_offset: 0.5
+
+  # How often should the calendar be fetched in seconds. This determines the time of the last changes applied, before a specific show is aired
+  fetching_frequency: 30
+  # The scheduling window defines when the entries of each timeslot are queued for play-out. The windows start at (timeslot.start - window_start) seconds
+  # and ends at (timeslot.end - window.end) seconds. Its also worth noting, that timeslots can only be deleted before the start of the window.
+  scheduling_window_start: 60
+  scheduling_window_end: 60
+  # How many seconds before the actual schedule time the entry should be pre-loaded. Note to provide enough timeout for
+  # contents which take longer to load (big files, bad connectivity to streams etc.). If the planned start time is in
+  # the past the offset is ignored and the entry is played as soon as possible
+  preload_offset: 15
+
+  # Sometimes it might take longer to get a stream connected. Here you can define a viable length.
+  # But note, that this may affect the preloading time (see `preload_offset`), hence affecting the
+  # overall playout, its delays and possible fallbacks
+  input_stream:
+    retry_delay: 1
+    max_retries: 10
+    buffer: 3.0
+
+  # Fade duration when selecting another mixer input (seconds)
+  fade:
+    in_time: 1.5
+    out_time: 1.5
diff --git a/src/aura_engine/app.py b/src/aura_engine/app.py
index c5fdec9033e384f2c5b2671e0ca21fef57c64834..52765e3155134d07f36eb0d079948537650401fa 100755
--- a/src/aura_engine/app.py
+++ b/src/aura_engine/app.py
@@ -64,7 +64,7 @@ class EngineRunner:
         """
         Constructor.
         """
-        self.config = config
+        self.config = config.config
         AuraLogger(self.config)
         self.logger = logging.getLogger("engine")
         self.engine = Engine()
diff --git a/src/aura_engine/base/config.py b/src/aura_engine/base/config.py
index 72211f940bfb83820c41a15899ace3755748c147..d95fe7ee6c185208d4080342bebab7755074ed3e 100644
--- a/src/aura_engine/base/config.py
+++ b/src/aura_engine/base/config.py
@@ -25,9 +25,68 @@ import logging
 import os
 import os.path
 import sys
-from configparser import ConfigParser
 from pathlib import Path
 
+import confuse
+
+template = {
+    "general": {
+        "log": {
+            "directory": str,
+            "level": confuse.OneOf(["debug", "info", "warning", "error", "critical"]),
+        },
+        "socket_dir": str,
+        "cache_dir": str,
+        "fallback": {"show_name": str, "show_id": int},
+    },
+    "monitoring": {
+        "mail": {
+            "host": str,
+            "port": int,
+            "user": str,
+            "pwd": str,
+            "from": str,
+            "subject_prefix": str,
+            "coordinator": {"enabled": bool, "mail": str},
+            "admin": {"enabled": bool, "mail": str},
+        },
+        "heartbeat": {"host": str, "port": int, "frequency": int},
+    },
+    "api": {
+        "steering": {"status": str, "calendar": str},
+        "tank": {"session": str, "secret": str, "status": str, "playlist": str},
+        "engine": {
+            "number": int,
+            "status": str,
+            "store_playlog": str,
+            "store_clock": str,
+            "store_health": str,
+        },
+    },
+    "scheduler": {
+        "db": {
+            "type": confuse.OneOf(["postgresql", "mysql", "sqlite"]),
+            "name": str,
+            "user": str,
+            "pwd": str,
+            "host": str,
+            "charset": str,
+        },
+        "audio": {
+            "source_folder": str,
+            "source_extension": str,
+            "playlist_folder": str,
+            "engine_latency_offset": float,
+        },
+        "fetching_frequency": int,
+        "scheduling_window_start": int,
+        "scheduling_window_end": int,
+        "preload_offset": int,
+        "input_stream": {"retry_delay": int, "max_retries": int, "buffer": float},
+        "fade": {"in_time": float, "out_time": float},
+    },
+}
+
 
 class AuraConfig:
     """
@@ -35,99 +94,62 @@ class AuraConfig:
     """
 
     instance = None
-    ini_path = ""
+    yaml_path = ""
+    confuse_config = None
+    config = None  # points to a validated config (hopefully later)
     logger = None
 
-    def __init__(self, ini_path="/etc/aura/engine.ini"):
+    def __init__(self, yaml_path="/etc/aura/engine.yaml"):
         """
-        Initialize the configuration, defaults to `/etc/aura/engine.ini`.
+        Initialize the configuration, defaults to `/etc/aura/engine.yaml`.
 
-        If this file doesn't exist it uses `./config/engine.ini` from
+        If this file doesn't exist it uses `./config/engine.yaml` from
         the project directory.
 
         Args:
-            ini_path(String): The path to the configuration file `engine.ini`
+            yaml_path(String): The path to the configuration file `engine.yaml`
 
         """
         self.logger = logging.getLogger("engine")
-        config_file = Path(ini_path)
+        config_file = Path(yaml_path)
         project_root = Path(__file__).parent.parent.parent.parent.absolute()
 
         if not config_file.is_file():
-            ini_path = f"{project_root}/config/engine.ini"
+            yaml_path = f"{project_root}/config/engine.yaml"
+
+        self.yaml_path = yaml_path
+        print(f"Using configuration at: {yaml_path}")
 
-        self.ini_path = ini_path
+        self.confuse_config = confuse.Configuration("engine")
+        self.confuse_config.set_file(yaml_path)
         self.load_config()
-        AuraConfig.instance = self
 
         # Defaults
-        self.set("install_dir", os.path.realpath(project_root))
-        self.set("config_dir", os.path.dirname(ini_path))
-        print(f"Using configuration at: {ini_path}")
+        self.confuse_config["install_dir"].set(os.path.realpath(project_root))
+        self.confuse_config["config_dir"].set(os.path.dirname(yaml_path))
+
+        AuraConfig.instance = self
 
     def init_version(self, version: dict):
         """
         Read and set the component version from VERSION file in project root.
         """
-        self.set("version_control", version.get("control"))
-        self.set("version_core", version.get("core"))
-        self.set("version_liquidsoap", version.get("liquidsoap"))
-
-    @staticmethod
-    def config():
-        """
-        Retrieve the global instances of the configuration.
-        """
-        return AuraConfig.instance
-
-    def set(self, key, value):
-        """
-        Set specific config property.
-
-        Args:
-            key (String): key
-            default (*): value
-
-        """
-        try:
-            self.__dict__[key] = int(value)
-        except ValueError:
-            self.__dict__[key] = str(value)
-
-    def get(self, key, default=None):
-        """
-        Get for some specific config property.
-
-        Args:
-            key (String): key
-            default (*): value
-
-        """
-        if key not in self.__dict__:
-            if default:
-                self.set(key, default)
-            else:
-                self.logger.warning(
-                    "Key " + key + " not found in configfile " + self.ini_path + "!"
-                )
-                return None
-
-        value = self.__dict__[key]
-        if value and isinstance(value, str):
-            value = os.path.expandvars(value)
-        return value
+        self.confuse_config["version_control"].set(version.get("control"))
+        self.confuse_config["version_core"].set(version.get("core"))
+        self.confuse_config["version_liquidsoap"].set(version.get("liquidsoap"))
 
     def get_database_uri(self):
         """
         Retrieve the database connection string.
         """
-        db_name = str(self.get("db_name"))
-        db_type = str(self.get("db_type"))
+        db_cfg = self.config.scheduler.db
+        db_name = db_cfg.name
+        db_type = db_cfg.type
         if db_type in {"mysql", "postgresql"}:
-            db_user = str(self.get("db_user"))
-            db_pass = str(self.get("db_pass"))
-            db_host = str(self.get("db_host"))
-            db_charset = self.get("db_charset", "utf8")
+            db_user = db_cfg.user
+            db_pass = db_cfg.pwd
+            db_host = db_cfg.host
+            db_charset = db_cfg.charset
             if db_type == "mysql":
                 return f"mysql://{db_user}:{db_pass}@{db_host}/{db_name}?charset={db_charset}"
             else:
@@ -145,27 +167,11 @@ class AuraConfig:
         """
         Set config defaults and load settings from file.
         """
-        if not os.path.isfile(self.ini_path):
-            self.logger.critical(self.ini_path + " not found  :(")
+        if not os.path.isfile(self.yaml_path):
+            self.logger.critical(self.yaml_path + " not found  :(")
             sys.exit(1)
 
-        # Read the file
-        f = open(self.ini_path, "r")
-        ini_str = f.read()
-        f.close()
-
-        # Parse the values
-        config_parser = ConfigParser()
-        try:
-            config_parser.read_string(ini_str)
-        except Exception as e:
-            self.logger.critical("Cannot read " + self.ini_path + "! Reason: " + str(e))
-            sys.exit(0)
-
-        for section in config_parser.sections():
-            for key, value in config_parser.items(section):
-                v = config_parser.get(section, key).replace('"', "").strip()
-                self.set(key, v)
+        self.config = self.confuse_config.get(template)
 
     def to_abs_path(self, path):
         """
@@ -176,16 +182,16 @@ class AuraConfig:
         if path.startswith("/"):
             return path
         else:
-            return self.get("install_dir") + "/" + path
+            return self.confuse_config["install_dir"].get() + "/" + path
 
     def abs_audio_store_path(self):
         """
         Return the absolute path to the audio store, based on the `audio_source_folder` setting.
         """
-        return self.to_abs_path(self.get("audio_source_folder"))
+        return self.to_abs_path(self.config.scheduler.audio.source_folder)
 
     def abs_playlist_path(self):
         """
         Return the absolute path to the playlist folder.
         """
-        return self.to_abs_path(self.get("audio_playlist_folder"))
+        return self.to_abs_path(self.config.scheduler.audio.playlist_folder)
diff --git a/src/aura_engine/base/logger.py b/src/aura_engine/base/logger.py
index a86ebc7d4795da7b784e071f03335d184b78463b..e0bc3933937ec9e743e5819b5b9f0dfbd6f6b2ed 100644
--- a/src/aura_engine/base/logger.py
+++ b/src/aura_engine/base/logger.py
@@ -53,7 +53,7 @@ class AuraLogger:
         """
         Retrieve the configured log level (default=INFO).
         """
-        lvl = self.config.get("log_level")
+        lvl = self.config.general.log.level
         mapping = {
             "debug": logging.DEBUG,
             "info": logging.INFO,
@@ -83,7 +83,9 @@ class AuraLogger:
 
         if not self.logger.hasHandlers():
             # create file handler for logger
-            file_handler = logging.FileHandler(self.config.get("log_dir") + "/" + name + ".log")
+            file_handler = logging.FileHandler(
+                self.config.general.log.directory + "/" + name + ".log"
+            )
             file_handler.setLevel(lvl)
 
             # create stream handler for logger
diff --git a/src/aura_engine/core/channels.py b/src/aura_engine/core/channels.py
index 6336bf12858b82d0d9dd3aef7bbf1855ef72ef6d..b2554bbd7c5ea566f74c93190031ce82ffb08d0e 100644
--- a/src/aura_engine/core/channels.py
+++ b/src/aura_engine/core/channels.py
@@ -148,7 +148,7 @@ class GenericChannel:
             mixer (Mixer): The mixer instance
 
         """
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.config().config
         self.logger = logging.getLogger("engine")
         self.mixer = mixer
         self.name = channel_name
diff --git a/src/aura_engine/core/client.py b/src/aura_engine/core/client.py
index f2482b177d9c18b0c0c2c160dec67ce40856d71e..a4e53373822795028e79500b2506efdcc77455da 100644
--- a/src/aura_engine/core/client.py
+++ b/src/aura_engine/core/client.py
@@ -50,7 +50,7 @@ class CoreClient:
         Initialize the client.
         """
         self.logger = logging.getLogger("engine")
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.instance.config
         self.event_dispatcher = event_dispatcher
         self.conn = CoreConnection()
 
@@ -153,7 +153,7 @@ class CoreClient:
         @private
 
         """
-        if self.config.get("log_level") == "debug":
+        if self.config.general.log_level == "debug":
             cmds = CoreClient.skip_log_commands
             base_cmd = command.split(" ")[0]
             if not base_cmd.startswith(cmds):
@@ -236,8 +236,8 @@ class CoreConnection:
         Initialize the connection.
         """
         self.logger = logging.getLogger("engine")
-        config = AuraConfig.config()
-        socket_path = config.get("socket_dir") + "/engine.sock"
+        config = AuraConfig.config().config
+        socket_path = config.config.general.socket_dir + "/engine.sock"
         self.socket_path = config.to_abs_path(socket_path)
         self.logger.debug(f"Using socket at '{self.socket_path}'")
 
diff --git a/src/aura_engine/core/mixer.py b/src/aura_engine/core/mixer.py
index 83022296781e1755f9c69c08ea53f767db173f69..ca933fce70ccb10be26a906f438d008c03501381 100644
--- a/src/aura_engine/core/mixer.py
+++ b/src/aura_engine/core/mixer.py
@@ -63,7 +63,7 @@ class Mixer:
             client (PlayoutClient): The client for controlling playout
 
         """
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.instance.config
         self.logger = logging.getLogger("engine")
         self.mixer_id = mixer_id
         self.client = client
@@ -234,7 +234,7 @@ class Mixer:
                 self.logger.info(msg)
                 return
 
-            fade_in_time = float(self.config.get("fade_in_time"))
+            fade_in_time = self.config.scheduler.fade_in_time
 
             if fade_in_time > 0:
                 self.fade_in_active = True
@@ -274,7 +274,7 @@ class Mixer:
                 self.logger.info(msg)
                 return
 
-            fade_out_time = float(self.config.get("fade_out_time"))
+            fade_out_time = self.config.scheduler.fade_out_time
 
             if fade_out_time > 0:
                 step = abs(fade_out_time) / current_volume
diff --git a/src/aura_engine/engine.py b/src/aura_engine/engine.py
index 20c29439f6a49a07b9123945ddf8957ed57f3d66..8cd0273c2a2a8d8fc5294882ae07c9c29721d9af 100644
--- a/src/aura_engine/engine.py
+++ b/src/aura_engine/engine.py
@@ -66,8 +66,8 @@ class Engine:
             raise Exception("Engine is already running!")
         Engine.instance = self
         self.logger = logging.getLogger("engine")
-        self.config = AuraConfig.config()
-        Engine.engine_time_offset = float(self.config.get("engine_latency_offset"))
+        self.config = AuraConfig.instance.config
+        Engine.engine_time_offset = self.config.scheduler.audio.engine_latency_offset
 
     def start(self):
         """
@@ -125,7 +125,7 @@ class Engine:
 
         def dispatch_fallback_event():
             timeslot = self.scheduler.timetable.get_current_timeslot()
-            fallback_show_name = self.config.get("fallback_show_name")
+            fallback_show_name = self.config.general.fallback_show_name
             self.event_dispatcher.on_fallback_active(timeslot, fallback_show_name)
 
         # Initialize state
@@ -155,8 +155,8 @@ class Engine:
         Update the config of playout with the current values.
         """
         playout_config = {
-            "fallback_show_id": int(self.config.get("fallback_show_id")),
-            "fallback_show_name": self.config.get("fallback_show_name"),
+            "fallback_show_id": self.config.general.fallback_show_id,
+            "fallback_show_name": self.config.general.fallback_show_name,
         }
         json_config = json.dumps(playout_config, ensure_ascii=False)
         response = self.playout.set_config(json_config)
@@ -261,7 +261,7 @@ class Player:
             event_dispatcher (EventDispather): Dispatcher for issuing events
 
         """
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.config().config
         self.logger = logging.getLogger("engine")
         self.event_dispatcher = event_dispatcher
         self.resource_map = ResourceMapping()
diff --git a/src/aura_engine/events.py b/src/aura_engine/events.py
index 86d463e41ed6a25c7d0256358bc03f288e4618b5..5a8e387f0c6d896e7b2812d7f74d8e1932315961 100644
--- a/src/aura_engine/events.py
+++ b/src/aura_engine/events.py
@@ -85,7 +85,7 @@ class EngineEventDispatcher:
         """
         self.subscriber_registry = dict()
         self.logger = logging.getLogger("engine")
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.instance.config
         self.engine = engine
 
         binding = self.attach(AuraMonitor)
diff --git a/src/aura_engine/plugins/clock.py b/src/aura_engine/plugins/clock.py
index 02a810054eb82f598fd9713cd93c4d7380b4d888..4bec67ed6144c9d650393a29224eaa0fb4eeda01 100644
--- a/src/aura_engine/plugins/clock.py
+++ b/src/aura_engine/plugins/clock.py
@@ -45,7 +45,7 @@ class ClockInfoHandler:
         Initialize.
         """
         self.logger = logging.getLogger("engine")
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.config().config
         self.api = SimpleRestApi()
         self.engine = engine
 
@@ -69,8 +69,8 @@ class ClockInfoHandler:
             return
 
         self.logger.info(f"Fallback '{fallback_name}' activated, clock update required")
-        fallback_show_id = self.config.get("fallback_show_id")
-        fallback_show_name = self.config.get("fallback_show_name")
+        fallback_show_id = self.config.general.fallback_show_id
+        fallback_show_name = self.config.general.fallback_show_name
 
         # Interpolate timeslot-less slot
         # TODO start time to be calculated based on previous timeslot (future station logic)
@@ -124,12 +124,12 @@ class ClockInfoHandler:
             built_upcoming.append(self.build_timeslot(upcoming_timeslot))
 
         data = {
-            "engineSource": self.config.get("api_engine_number"),
+            "engineSource": self.config.api.engine.number,
             "currentTimeslot": self.build_timeslot(active_timeslot, active_type),
             "upcomingTimeslots": built_upcoming,
             "plannedPlaylist": self.build_playlist(active_playlist),
         }
-        url = self.config.get("api_engine_store_clock")
+        url = self.config.api.engine.store_clock
         self.logger.info(f"PUT clock info to '{url}': \n{data}")
         self.api.put(url, data=data)
 
diff --git a/src/aura_engine/plugins/monitor.py b/src/aura_engine/plugins/monitor.py
index c5e9bb39d1300843bacdfa428e095bea5f5754d4..4f29f068c6775d67676b5fca7ba99b9038e6d744 100644
--- a/src/aura_engine/plugins/monitor.py
+++ b/src/aura_engine/plugins/monitor.py
@@ -100,9 +100,9 @@ class AuraMonitor:
 
         # Heartbeat settings
         self.heartbeat_running = False
-        self.heartbeat_server = self.config.get("heartbeat_server")
-        self.heartbeat_port = self.config.get("heartbeat_port")
-        self.heartbeat_frequency = self.config.get("heartbeat_frequency")
+        self.heartbeat_server = self.config.monitoring.heartbeat.host
+        self.heartbeat_port = self.config.monitoring.heartbeat.port
+        self.heartbeat_frequency = self.config.monitoring.heartbeat.frequency
         self.heartbeat_socket = socket(AF_INET, SOCK_DGRAM)
 
         self.engine_id = self.get_engine_id()
@@ -197,8 +197,8 @@ class AuraMonitor:
         body["isHealthy"] = is_healthy
         body["details"] = json.dumps(data, default=str)
         json_data = json.dumps(body, default=str)
-        url = self.config.get("api_engine_store_health")
-        url = url.replace("${ENGINE_NUMBER}", str(self.config.get("api_engine_number")))
+        url = self.config.api.engine.store_health
+        url = url.replace("${ENGINE_NUMBER}", str(self.config.api.engine.number))
         headers = {"content-type": "application/json"}
         response = requests.Response()
         response.status_code = 404
@@ -230,28 +230,26 @@ class AuraMonitor:
         Request the current status of all components.
         """
         self.engine.init_version()
-        ctrl_version = self.config.get("version_control")
-        core_version = self.config.get("version_core")
-        liq_version = self.config.get("version_liquidsoap")
+        ctrl_version = self.config.version.control
+        core_version = self.config.version.core
+        liq_version = self.config.version.liquidsoap
 
         self.status["engine"]["version"] = ctrl_version
         self.status["lqs"]["version"] = {"core": core_version, "liquidsoap": liq_version}
         self.status["lqs"]["outputs"] = self.engine.player.mixer.get_outputs()
         self.status["lqs"]["mixer"] = self.engine.player.mixer.get_inputs()
-        self.status["api"]["steering"]["url"] = self.config.get("api_steering_status")
+        self.status["api"]["steering"]["url"] = self.config.api.steering.status
         self.status["api"]["steering"]["available"] = self.validate_url_connection(
-            self.config.get("api_steering_status")
+            self.config.api.steering.status
         )
-        self.status["api"]["tank"]["url"] = self.config.get("api_tank_status")
+        self.status["api"]["tank"]["url"] = self.config.api.tank.status
         self.status["api"]["tank"]["available"] = self.validate_url_connection(
-            self.config.get("api_tank_status")
+            self.config.api.tank.status
         )
-        self.status["api"]["tank"]["status"] = self.get_url_response(
-            self.config.get("api_tank_status")
-        )
-        self.status["api"]["engine"]["url"] = self.config.get("api_engine_status")
+        self.status["api"]["tank"]["status"] = self.get_url_response(self.config.api.tank.status)
+        self.status["api"]["engine"]["url"] = self.config.api.engine.status
         self.status["api"]["engine"]["available"] = self.validate_url_connection(
-            self.config.get("api_engine_status")
+            self.config.api.engine.status
         )
 
         self.update_vitality_status()
@@ -278,7 +276,7 @@ class AuraMonitor:
         """
         if self.has_valid_status(True):
             # Always check status, but only send heartbeat if wanted so
-            if self.config.get("heartbeat_server") != "":
+            if self.config.monitoring.heartbeat.server != "":
                 self.heartbeat_socket.sendto(
                     str.encode("OK"), (self.heartbeat_server, self.heartbeat_port)
                 )
@@ -306,7 +304,7 @@ class AuraMonitor:
                     {"engine_id": self.engine_id, "status": status}
                 )
 
-        heartbeat_frq = self.config.get("heartbeat_frequency", 1)
+        heartbeat_frq = self.config.monitoring.heartbeat.frequency  # default: 1
         if int(heartbeat_frq or 0) < 1:
             heartbeat_frq = 1
         threading.Timer(heartbeat_frq, self.heartbeat).start()
diff --git a/src/aura_engine/scheduling/api.py b/src/aura_engine/scheduling/api.py
index 0fbe806c8e6f9a64b980948fe287232ea78e3b89..10ccd979b7daeec9100cb2a8236daafeb6558103 100644
--- a/src/aura_engine/scheduling/api.py
+++ b/src/aura_engine/scheduling/api.py
@@ -66,12 +66,12 @@ class ApiFetcher(threading.Thread):
         """
         Initialize the API Fetcher.
         """
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.instance.config
         self.logger = logging.getLogger("engine")
-        cache_location = self.config.get("cache_dir")
+        cache_location = self.config.general.cache_dir
         self.api = SimpleCachedRestApi(SimpleRestApi(), cache_location)
-        self.url_api_timeslots = self.config.get("api_steering_calendar")
-        self.url_api_playlist = self.config.get("api_tank_playlist")
+        self.url_api_timeslots = self.config.api.steering.calendar
+        self.url_api_playlist = self.config.api.tank.playlist
         self.queue = queue.Queue()
         self.stop_event = threading.Event()
 
@@ -82,8 +82,8 @@ class ApiFetcher(threading.Thread):
             ApiFetcher.MODEL_PLID_SHOW: ApiFetcher.API_PLID_SHOW,
         }
 
-        tank_session = self.config.get("api_tank_session")
-        tank_secret = self.config.get("api_tank_secret")
+        tank_session = self.config.api.tank.session
+        tank_secret = self.config.api.tank.secret
         self.tank_headers = {
             "Authorization": f"Bearer {tank_session}:{tank_secret}",
             "content-type": "application/json",
diff --git a/src/aura_engine/scheduling/programme.py b/src/aura_engine/scheduling/programme.py
index a16287edd4964bb7057ef820f7b48238e95a709d..24ab8fd08878d0ae17cd3ec9690a8cf8092ee683 100644
--- a/src/aura_engine/scheduling/programme.py
+++ b/src/aura_engine/scheduling/programme.py
@@ -50,7 +50,7 @@ class ProgrammeService:
     programme_store = None
 
     def __init__(self):
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.config().config
         self.logger = logging.getLogger("engine")
         self.programme_store = ProgrammeStore()
 
@@ -213,8 +213,8 @@ class ProgrammeService:
         Check if the timeslot is within the scheduling window.
         """
         now_unix = Engine.engine_time()
-        window_start = self.config.get("scheduling_window_start")
-        window_end = self.config.get("scheduling_window_end")
+        window_start = self.config.scheduler.scheduling_window_start
+        window_end = self.config.scheduler.scheduling_window_end
 
         if (
             timeslot.start_unix - window_start < now_unix
@@ -247,7 +247,7 @@ class ProgrammeStore:
     m3u_processor = None
 
     def __init__(self):
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.instance.config
         self.logger = logging.getLogger("engine")
         self.m3u_processor = M3UPlaylistProcessor()
 
@@ -312,7 +312,7 @@ class ProgrammeStore:
 
         """
         now_unix = SU.timestamp()
-        scheduling_window_start = self.config.get("scheduling_window_start")
+        scheduling_window_start = self.config.scheduler.scheduling_window_start
 
         local_timeslots = Timeslot.get_timeslots(datetime.now())
         for local_timeslot in local_timeslots:
diff --git a/src/aura_engine/scheduling/scheduler.py b/src/aura_engine/scheduling/scheduler.py
index 92a902ab8b2584f2b6fb11a56c17ab9457e56d90..0313ae644d576c20d392acee8b5a622a2cef11e1 100644
--- a/src/aura_engine/scheduling/scheduler.py
+++ b/src/aura_engine/scheduling/scheduler.py
@@ -65,7 +65,7 @@ class AuraScheduler(threading.Thread):
     is_engine_ready: bool = None
 
     def __init__(self, engine):
-        self.config = AuraConfig.config()
+        self.config = AuraConfig.config().config
         self.logger = logging.getLogger("engine")
         self.timetable = ProgrammeService()
         self.timetable_renderer = TimetableRenderer(self)
@@ -101,7 +101,7 @@ class AuraScheduler(threading.Thread):
         while not self.exit_event.is_set():
             try:
                 self.config.load_config()
-                seconds_to_wait = int(self.config.get("fetching_frequency"))
+                seconds_to_wait = self.config.scheduler.fetching_frequency
                 msg = f"== start fetching new timeslots (every {seconds_to_wait} seconds) =="
                 self.logger.info(SU.cyan(msg))
 
@@ -392,8 +392,8 @@ class AuraScheduler(threading.Thread):
 
         now_unix = Engine.engine_time()
         len_before = len(timeslots)
-        window_start = self.config.get("scheduling_window_start")
-        window_end = self.config.get("scheduling_window_end")
+        window_start = self.config.scheduler.scheduling_window_start
+        window_end = self.config.scheduler.scheduling_window_end
         timeslots = list(
             filter(
                 lambda t: (t.start_unix - window_start) < now_unix
@@ -445,7 +445,7 @@ class TimeslotCommand(EngineExecutor):
         self.engine = engine
 
         now_unix = SU.timestamp()
-        fade_out_time = float(self.config.get("fade_out_time"))
+        fade_out_time = self.config.scheduler.fade_out_time
         start_fade_in = timeslot.start_unix - now_unix
         start_fade_out = timeslot.end_unix - now_unix - fade_out_time
         self.logger.debug(
@@ -511,7 +511,7 @@ class PlayCommand(EngineExecutor):
     """
 
     engine: Engine = None
-    config: AuraConfig = None
+    config = None
 
     def __init__(self, engine: Engine, entries):
         """Initialize the play command.
@@ -520,10 +520,10 @@ class PlayCommand(EngineExecutor):
             engine (Engine): The engine
             entries (PlaylistEntry): One or more playlist entries to be started
         """
-        self.config = AuraConfig()
+        self.config = AuraConfig.instance.config
         self.engine = engine
 
-        preload_offset = self.config.get("preload_offset")
+        preload_offset = self.config.scheduler.preload_offset
         start_preload = entries[0].start_unix - preload_offset
         start_play = entries[0].start_unix
         msg = (
diff --git a/tests/test_config.py b/tests/test_config.py
index 0d7c74138aeab06a7c4a7e8730e702ccfcd2caa3..e262270cca779fa2da10862fc1dfe675d2c7754c 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -39,30 +39,31 @@ class TestConfig(unittest.TestCase):
         print(self._testMethodName)
 
         # Check if config is available
-        self.assertIsNotNone(self.config.ini_path)
+        self.assertIsNotNone(self.config.yaml_path)
 
         # Check if "install_dir" is a valid directory (is evaluated at runtime)
-        self.assertTrue(os.path.isdir(self.config.get("install_dir")))
+        self.assertTrue(os.path.isdir(self.config.confuse_config["install_dir"].get()))
+
+        # Reference to confuse config
+        cfg = self.config.config
 
         # Check API Urls
-        self.assertTrue(validators.url(self.config.get("api_steering_status")))
-        self.assertTrue(validators.url(self.config.get("api_steering_calendar")))
-        self.assertTrue(validators.url(self.config.get("api_tank_status")))
-        tank_playlist_url = self.config.get("api_tank_playlist").replace("${ID}", "1")
+        self.assertTrue(validators.url(cfg.api.steering.status))
+        self.assertTrue(validators.url(cfg.api.steering.calendar))
+        self.assertTrue(validators.url(cfg.api.tank.status))
+        tank_playlist_url = cfg.api.tank.playlist.replace("${ID}", "1")
         self.assertTrue(validators.url(tank_playlist_url))
-        self.assertTrue(validators.url(self.config.get("api_engine_status")))
-        self.assertTrue(validators.url(self.config.get("api_engine_store_playlog")))
-        self.assertTrue(validators.url(self.config.get("api_engine_store_clock")))
-        engine_health_url = self.config.get("api_engine_store_health").replace(
-            "${ENGINE_NUMBER}", "1"
-        )
+        self.assertTrue(validators.url(cfg.api.engine.status))
+        self.assertTrue(validators.url(cfg.api.engine.store_playlog))
+        self.assertTrue(validators.url(cfg.api.engine.store_clock))
+        engine_health_url = cfg.api.engine.store_health.replace("${ENGINE_NUMBER}", "1")
         self.assertTrue(validators.url(engine_health_url))
 
         # Check if database settings are set
-        self.assertIsNotNone(self.config.get("db_user"))
-        self.assertIsNotNone(self.config.get("db_pass"))
-        self.assertIsNotNone(self.config.get("db_name"))
-        self.assertIsNotNone(self.config.get("db_host"))
+        self.assertIsNotNone(cfg.scheduler.db.user)
+        self.assertIsNotNone(cfg.scheduler.db.pwd)
+        self.assertIsNotNone(cfg.scheduler.db.name)
+        self.assertIsNotNone(cfg.scheduler.db.host)
 
 
 if __name__ == "__main__":
diff --git a/tests/test_logger.py b/tests/test_logger.py
index ac532bd80f275a74bc8ebf9244f8bc9d709811ef..4344b55c9b30b13e76c3bfce3b4a8b916602a783 100644
--- a/tests/test_logger.py
+++ b/tests/test_logger.py
@@ -31,7 +31,7 @@ class TestLogger(unittest.TestCase):
     aura_logger = None
 
     def setUp(self):
-        self.config = AuraConfig()
+        self.config = AuraConfig().config
         self.aura_logger = AuraLogger(self.config)
 
     def test_logger(self):
diff --git a/tests/test_simple_api.py b/tests/test_simple_api.py
index 12aa24c45c4c7816fafd0d682a416803e94a036c..05cbd9f59e64adea5a9e90cfe2f92dd2be5bcc80 100644
--- a/tests/test_simple_api.py
+++ b/tests/test_simple_api.py
@@ -101,7 +101,7 @@ class TestApi(unittest.TestCase):
         print(self._testMethodName)
 
         # Check if config is available
-        self.assertIsNotNone(self.config.ini_path)
+        self.assertIsNotNone(self.config.yaml_path)
 
     def test_clean_dict(self):
         print(self._testMethodName)
diff --git a/tests/test_simple_api_cached.py b/tests/test_simple_api_cached.py
index e1168b550c9d6082e31eb29eafcd941ba92b51f3..6c96c5c822bac368b4f4188d91145509bacadf32 100644
--- a/tests/test_simple_api_cached.py
+++ b/tests/test_simple_api_cached.py
@@ -63,7 +63,7 @@ class TestCachedApi(unittest.TestCase):
 
     def setUp(self):
         self.config = AuraConfig()
-        cache_location = self.config.get("cache_dir")
+        cache_location = self.config.config.general.cache_dir
         self.api = SimpleCachedRestApi(SimpleRestApi(), cache_location)
 
     #
@@ -74,7 +74,7 @@ class TestCachedApi(unittest.TestCase):
         print(self._testMethodName)
 
         # Check if config is available
-        self.assertIsNotNone(self.config.ini_path)
+        self.assertIsNotNone(self.config.yaml_path)
 
     def test_build_filename(self):
         url = "https://dashboard.aura.radio/steering/api/v1/playout"