diff --git a/README.md b/README.md
index 1af7ab0..d94534f 100644
--- a/README.md
+++ b/README.md
@@ -193,6 +193,25 @@ DNS_ADD_COMMAND=/home/root/getssl/dns_scripts/dns_add_cpanel
DNS_DEL_COMMAND=/home/root/getssl/dns_scripts/dns_del_cpanel
```
+
+### ISPConfig
+
+There is a need to create a remote user in `ISPConfig` to enable the remote API access.
+
+You need to go to `System -> Remote Users` and then enable the features for the remote user such as `DNS zone functions`.
+
+PHP is required to exeucte soap functions in file ispconfig_soap.php.
+```sh
+DNS_ADD_COMMAND="/home/root/getssl/dns_scripts/dns_add_ispconfig"
+DNS_DEL_COMMAND="/home/root/getssl/dns_scripts/dns_del_ispconfig"
+
+export ISPCONFIG_REMOTE_USER_NAME="ussename"
+export ISPCONFIG_REMOTE_USER_PASSWORD="password"
+export ISPCONFIG_SOAP_LOCATION="https://localhost:8080/remote/index.php"
+export ISPCONFIG_SOAP_URL="https://localhost:8080/remote/"
+```
+
+
Create the wildcard certificate (need to use quotes to prevent globbing):
```sh
diff --git a/dns_scripts/dns_add_ispconfig b/dns_scripts/dns_add_ispconfig
new file mode 100644
index 0000000..13eb548
--- /dev/null
+++ b/dns_scripts/dns_add_ispconfig
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+# Need to add your API key below or set as env variable
+CURR_PATH="`dirname \"$0\"`"
+
+ispconfig_user="$ISPCONFIG_REMOTE_USER_NAME"
+ispconfig_pass="$ISPCONFIG_REMOTE_USER_PASSWORD"
+
+soap_location="$ISPCONFIG_SOAP_LOCATION"
+soap_uri="$ISPCONFIG_SOAP_URL"
+
+# This script adds a token to ispconfig database DNS for the ACME challenge
+# usage dns_add_ispconfig "domain name" "token"
+# return codes are;
+# 0 - success
+# 1 - error in input
+# 2 - error within internal processing
+# 3 - error in result ( domain not found in dynu.com etc)
+
+fulldomain="${1}"
+token="${2}"
+
+# Check initial parameters
+if [[ -z "$fulldomain" ]]; then
+ echo "DNS script requires full domain name as first parameter"
+ exit 1
+fi
+
+if [[ -z "$token" ]]; then
+ echo "DNS script requires challenge token as second parameter"
+ exit 1
+fi
+
+response=$(php $CURR_PATH/ispconfig_soap.php \
+ --action="add" \
+ --domain="$fulldomain" \
+ --token="$token" \
+ --ispconfig_user="$ispconfig_user" \
+ --ispconfig_pass="$ispconfig_pass" \
+ --soap_location="$soap_location" \
+ --soap_uri="$soap_uri")
+
+echo $response
+
+exit 0
\ No newline at end of file
diff --git a/dns_scripts/dns_del_ispconfig b/dns_scripts/dns_del_ispconfig
new file mode 100644
index 0000000..fb95685
--- /dev/null
+++ b/dns_scripts/dns_del_ispconfig
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+# Need to add your API key below or set as env variable
+CURR_PATH="`dirname \"$0\"`"
+
+ispconfig_user="$ISPCONFIG_REMOTE_USER_NAME"
+ispconfig_pass="$ISPCONFIG_REMOTE_USER_PASSWORD"
+
+soap_location="$ISPCONFIG_SOAP_LOCATION"
+soap_uri="$ISPCONFIG_SOAP_URL"
+
+# This script adds a token to ispconfig database DNS for the ACME challenge
+# usage dns_add_ispconfig "domain name" "token"
+# return codes are;
+# 0 - success
+# 1 - error in input
+# 2 - error within internal processing
+# 3 - error in result ( domain not found in dynu.com etc)
+
+fulldomain="${1}"
+token="${2}"
+
+# Check initial parameters
+if [[ -z "$fulldomain" ]]; then
+ echo "DNS script requires full domain name as first parameter"
+ exit 1
+fi
+
+if [[ -z "$token" ]]; then
+ echo "DNS script requires challenge token as second parameter"
+ exit 1
+fi
+
+response=$(php $CURR_PATH/ispconfig_soap.php \
+ --action="del" \
+ --domain="$fulldomain" \
+ --token="$token" \
+ --ispconfig_user="$ispconfig_user" \
+ --ispconfig_pass="$ispconfig_pass" \
+ --soap_location="$soap_location" \
+ --soap_uri="$soap_uri")
+
+echo $response
+
+exit 0
\ No newline at end of file
diff --git a/dns_scripts/ispconfig_soap.php b/dns_scripts/ispconfig_soap.php
new file mode 100644
index 0000000..66ddec8
--- /dev/null
+++ b/dns_scripts/ispconfig_soap.php
@@ -0,0 +1,140 @@
+ $soap_location,
+ 'uri' => $soap_uri,
+ 'trace' => 1,
+ 'exceptions' => 1,
+ 'stream_context' => stream_context_create(
+ array(
+ 'ssl' =>
+ array(
+ 'verify_peer' => false,
+ 'verify_peer_name' => false
+ )
+ )
+ )
+ )
+);
+
+try {
+
+ if ($session_id = $client->login($username, $password)) {
+ //echo 'Logged in successfully. Session ID:' . $session_id . '
';
+ }
+
+ // Get all zone
+ $zones = $client->dns_zone_get($session_id, -1);
+
+ $zone_id = 0;
+ $client_id = 0;
+ $server_id = 0;
+
+ foreach ($zones as $zone) {
+ // Find zone that needs to update
+ if (preg_match("/" . $zone["origin"] . "/", $fulldomain . ".")) {
+ $zone_id = $zone["id"];
+ $sys_userid = $zone["sys_userid"];
+ $server_id = $zone["server_id"];
+ }
+ }
+
+ //Get client id
+ $client_id = $client->client_get_id($session_id, $sys_userid);
+
+ if ($client_id == 0) {
+ exit;
+ }
+
+ // Get all domain records of type txt
+ // Bug it retrieves all domain records
+ $dns_records = $client->dns_txt_get($session_id, -1);
+
+ $dns_record_id = 0;
+
+ foreach ($dns_records as $dns_record) {
+ if ($dns_record["zone"] == $zone_id && $dns_record["type"] == "TXT" && $dns_record["name"] == "_acme-challenge.{$fulldomain}.") {
+ $dns_record_id = $dns_record["id"];
+ }
+ }
+
+ // Add if zero else update
+
+ $date = new DateTime();
+
+ switch ($action) {
+
+ case "add":
+ if ($dns_record_id == 0) {
+
+ $dns_record = array(
+ "server_id" => $server_id,
+ "zone" => $zone_id,
+ "name" => "_acme-challenge.{$fulldomain}.",
+ "type" => "txt",
+ "data" => $token,
+ "aux" => 111,
+ "ttl" => 300,
+ "active" => 'y',
+ "stamp" => date_format($date, 'Y-m-d H:i:s'),
+ "serial" => date_format($date, 'Ymds')
+ );
+
+ $result = $client->dns_txt_add($session_id, $client_id, $dns_record);
+
+ echo "Created record for domain {$fulldomain} with token $token\n";
+ } else {
+
+ $dns_record["data"] = $token;
+ $dns_record["stamp"] = date_format($date, 'Y-m-d H:i:s');
+ $dns_record["serial"] = date_format($date, 'YmdH');
+
+ $result = $client->dns_txt_update($session_id, $client_id, $dns_record_id, $dns_record);
+ echo "Updated the record for domain {$fulldomain} with token $token\n";
+ }
+
+ break;
+
+ case "del":
+
+ if ($dns_record_id > 0) {
+
+ $result = $client->dns_txt_delete($session_id, $dns_record_id);
+
+ if ($result) {
+ echo "The record was deleted from domain {$fulldomain} successfully\n";
+ } else {
+ echo "Failed to delete the record for domain {$fulldomain}\n";
+ }
+ } else {
+
+ echo "The record was not found for deletion\n";
+ }
+
+ break;
+ default:
+ echo "No action was specified as parameter\n";
+ break;
+ }
+
+ if ($client->logout($session_id)) {
+ //echo 'Logged out.
';
+ }
+} catch (SoapFault $e) {
+ echo $client->__getLastResponse();
+ die('SOAP Error: ' . $e->getMessage());
+}
diff --git a/getssl b/getssl
index 7be6551..c02bb6c 100755
--- a/getssl
+++ b/getssl
@@ -283,6 +283,7 @@
# 2021-12-22 Don't show usage if run with --upgrade (#728)
# 2021-12-23 Don't use +idnout if dig shows a warning (#688)
# 2022-01-06 Support --account-id (#716)(2.46)
+# 2022-03-09 Support for ISPConfig API (2.47)
# ----------------------------------------------------------------------------------------
case :$SHELLOPTS: in