diff --git a/inwx-acme.md b/inwx-acme.md
new file mode 100644
index 0000000..14bd2d9
--- /dev/null
+++ b/inwx-acme.md
@@ -0,0 +1,142 @@
+This hook utilizes the xml-rpc api of http://inwx.com for handling dns-01 type challenges.
+Its only dependencies are bash, libxml2 and curl.
+
+The hook expects to find inwx credentials in `$BASEDIR/inwx-acme.auth`:
+
+```
+#!/usr/bin/bash
+# inwx-acme.auth
+
+user='your inwx username'
+pass='your inwx password'
+```
+
+``` bash
+#!/usr/bin/bash
+# inwx-acme
+
+# Copyright (c) Joakim Reinert. All rights reserved.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+API_URL='https://api.domrobot.com/xmlrpc/'
+TMPDIR='/tmp/inwx-acme'
+
+source "$BASEDIR/inwx-acme.auth" # contains user and pass variables
+
+USER=$user
+PASS=$pass
+
+build_method_call() {
+ local method_name=$1
+ shift
+ echo -n ""
+ echo -n ""
+ echo -n "$method_name"
+ echo -n ""
+
+ for param in "$@"; do
+ echo -n "$param"
+ done
+
+ echo -n "$(build_param "user" "$USER")"
+ echo -n "$(build_param "pass" "$PASS")"
+
+ echo -n ""
+ echo -n ""
+}
+
+build_param() {
+ local name=$1
+ local value=$2
+ local type=${3:-string}
+ echo -n ''
+ echo -n "$name"
+ echo -n "<$type>"
+ if [[ "$type" = 'string' ]]; then
+ echo -n ""
+ else
+ echo -n "$value"
+ fi
+ echo -n "$type>"
+ echo -n ""
+}
+
+build_create_record_call() {
+ local domain=$1
+ local name=$2
+ local type=$3
+ local content=$4
+ local ttl=3600
+
+ build_method_call 'nameserver.createRecord' \
+ "$(build_param 'domain' $domain)" \
+ "$(build_param 'name' $name)" \
+ "$(build_param 'type' $type)" \
+ "$(build_param 'content' $content)" \
+ "$(build_param 'ttl' $ttl 'int')"
+}
+
+build_list_call() {
+ build_method_call 'nameserver.list'
+}
+
+build_delete_record_call() {
+ local id=$1
+ build_method_call 'nameserver.deleteRecord' \
+ "$(build_param 'id' $id)"
+}
+
+method_call() {
+ local call=$1
+ local result=$(curl -s -c "$TMPDIR/cookies" -d "$call" -H 'Content-Type: text/xml' "$API_URL")
+ local xpath='//methodResponse//params//member/name[text()="code"]/../value/int/text()'
+ local code=$(echo "$result" | xmllint --xpath "$xpath" -)
+ if [ $code = 1000 ]; then
+ echo "$result"
+ return 0
+ else
+ echo "$result" >&2
+ return 1
+ fi
+}
+
+deploy_challenge() {
+ local domain
+ local subdomain
+ if [[ -z "${1/*.*.*/}" ]]; then
+ domain=${1#*.}
+ subdomain=${1%%.*}
+ else
+ domain=$1
+ subdomain=''
+ fi
+ local token=$2
+
+ local result=$(method_call \
+ "$(build_create_record_call "$domain" "_acme-challenge.$subdomain" 'TXT' "$token")")
+ local code=$?
+ local xpath='//methodResponse//params//member/name[text()="id"]/../value/int/text()'
+ echo "$result" | xmllint --xpath "$xpath" -
+ return $code
+}
+
+clean_challenge() {
+ local record_id=$1
+ method_call \
+ "$(build_delete_record_call "$record_id")" > /dev/null
+}
+
+mkdir -p "$TMPDIR"
+
+case $1 in
+'deploy_challenge')
+ deploy_challenge "$2" "$4" > "$TMPDIR/$2.id"
+ ;;
+'clean_challenge')
+ clean_challenge "$(cat "$TMPDIR/$2.id")" || exit 1
+ rm "$TMPDIR/$2.id"
+ ;;
+esac
+```
\ No newline at end of file