diff --git a/nixarr/default.nix b/nixarr/default.nix
index 4107a43..02fac7a 100644
--- a/nixarr/default.nix
+++ b/nixarr/default.nix
@@ -69,6 +69,46 @@ in {
       '';
     };
 
+    ddns.njalla = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          **Required options:**
+
+          - [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile)
+
+          Whether or not to enable DDNS for a [Njalla](https://njal.la/)
+          domain.
+        '';
+      };
+
+      keysFile = mkOption {
+        type = with types; nullOr path;
+        default = null;
+        description = ''
+          A path to a JSON-file containing key value pairs of domains and keys.
+
+          To get the keys, create a dynamic njalla record. Upon creation
+          you should see something like the following command suggested:
+
+          ```
+            curl "https://njal.la/update/?h=jellyfin.example.com&k=zeubesojOLgC2eJC&auto"
+          ```
+
+          Then the JSON-file you give here should be:
+
+          ```json
+            {
+              "jellyfin.example.com": "zeubesojOLgC2eJC"
+            }
+          ```
+
+          You can, of course, add more key-value pairs than just one.
+        '';
+      };
+    };
+
     vpn = {
       enable = mkOption {
         type = types.bool;
@@ -146,6 +186,13 @@ in {
           to be set, but it was not.
         '';
       }
+      {
+        assertion = cfg.ddns.njalla.enable -> cfg.ddns.njalla.keysFile != null;
+        message = ''
+          The nixarr.ddns.njalla.enable option requires the
+          nixarr.ddns.njalla.keysFile option to be set, but it was not.
+        '';
+      }
     ];
 
     users.groups = {
@@ -230,5 +277,63 @@ in {
       openTcpPorts = cfg.vpn.openTcpPorts;
       openUdpPorts = cfg.vpn.openUdpPorts;
     };
+
+    systemd.timers = mkIf cfg.ddns.njalla.enable{
+      timers = {
+        ddnsNjalla = {
+          Unit.Description = "Timer for setting the njalla DDNS records";
+
+          Timer = {
+            OnBootSec = "5min"; # Run 5 minutes after system boot
+            OnCalendar = "hourly";
+            Persistent = "true"; # Run service immediately if last window was missed
+            RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
+          };
+
+          Install.WantedBy = ["timers.target"];
+        };
+      };
+    };
+
+    systemd.services = let 
+      ddns-njalla = pkgs.writeShellApplication {
+        name = "ddns-njalla";
+
+        runtimeInputs = with pkgs; [ curl jq ];
+
+        # Thanks chatgpt...
+        text = ''
+          # Path to the JSON file
+          json_file="${cfg.ddns.njalla.keysFile}"
+
+          # Convert the JSON object into a series of tab-separated key-value pairs using jq
+          # - `to_entries[]`: Convert the object into an array of key-value pairs.
+          # - `[.key, .value]`: For each pair, create an array containing the key and the value.
+          # - `@tsv`: Convert the array to a tab-separated string.
+          # The output will be a series of lines, each containing a key and a value separated by a tab.
+          jq_command='to_entries[] | [.key, .value] | @tsv'
+
+          # Read the converted output line by line
+          # - `IFS=$'\t'`: Use the tab character as the field separator.
+          # - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator.
+          while IFS=$'\t' read -r key val; do
+            # For each key-value pair, execute the curl command
+            # Replace `''${key}` and `''${val}` in the URL with the actual key and value.
+            curl "https://njal.la/update/?h=''${key}&k=''${val}&auto"
+          done < <(jq -r "$jq_command" "$json_file")
+        '';
+      };
+    in mkIf cfg.ddns.njalla.enable {
+      services = {
+        ddnsNjalla = {
+          Unit.Description = "Sets the njalla DDNS records";
+
+          Service = {
+            ExecStart = getExe ddns-njalla;
+            Type = "oneshot";
+          };
+        };
+      };
+    };
   };
 }