So liest, setzt und pflegst du DNS-Einträge per API. Im Mittelpunkt steht der Upsert, mit dem du einen Record in einem einzigen Aufruf anlegst oder aktualisierst. Am Ende steht ein fertiges DynDNS-Skript zum Kopieren.
- Records auflisten und einzeln pflegen
- Upsert: anlegen oder aktualisieren in einem Schritt
- Ganze Zonen exportieren und importieren
In allen Beispielen steht deine-domain.de für deine Domain und sk_live_XXXX für deinen Token. Als IDs kannst du überall die Domain oder ihre numerische ID verwenden.
Records auflisten
curl --request GET \
--url https://api.pph.systems/api/domains/deine-domain.de/records \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk_live_XXXX'
Jeder Record kommt mit id, name, full_name, type, content, ttl und priority. Wichtig ist das Feld editable. Systemrecords wie NS und SOA stehen zwar in der Liste, sind aber nicht editierbar.
{
"data": {
"domain": "deine-domain.de",
"records": [
{
"id": 101,
"name": "www",
"full_name": "www.deine-domain.de",
"type": "A",
"content": "192.0.2.1",
"ttl": 300,
"editable": true,
"priority": null
}
],
"total": 1
}
}
Mit dem Parameter name filterst du auf einen bestimmten Recordnamen, mit editable=true blendest du die Systemrecords aus.
Upsert: anlegen oder aktualisieren
Der Upsert ist das nützlichste Werkzeug für Automatisierung. Du gibst Name, Typ und Wert an. Existiert bereits ein Record mit diesem Namen und Typ, wird er aktualisiert. Wenn nicht, wird er angelegt. Du musst also vorher nicht prüfen, ob der Record schon da ist.
curl --request PATCH \
--url https://api.pph.systems/api/domains/deine-domain.de/record/upsert \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk_live_XXXX' \
--header 'Content-Type: application/json' \
--data '{ "record_name": "home", "record_type": "A", "record_content": "192.0.2.10" }'
Beim ersten Aufruf wird der Record angelegt:
{
"data": { "updated": [ { "id": 456439, "type": "A", "content": "192.0.2.10", "ttl": 43200 } ] },
"message": "DNS record created successfully."
}
Rufst du dieselbe Kombination aus Name und Typ mit einem neuen Wert erneut auf, bleibt die id gleich und nur der Inhalt ändert sich. Der Text in message wechselt auf „updated“:
{
"data": { "updated": [ { "id": 456439, "type": "A", "content": "192.0.2.20", "ttl": 43200 } ] },
"message": "DNS record(s) updated successfully."
}
Optional kannst du record_ttl mitgeben, und bei MX– oder SRV-Records record_prio.
Einzelne Records gezielt bearbeiten
Wenn du einen bestimmten Record über seine ID ansprechen willst, gibt es drei weitere Routen:
- Anlegen:
POST /domains/deine-domain.de/records. Mitreplace_existing=trueersetzt du einen gleichnamigen Record, statt einen Fehler zu bekommen. - Ändern: Über die Record-ID änderst du gezielt Wert, Name, Typ, TTL oder Priorität eines einzelnen Records.
- Löschen: Über die Record-ID entfernst du einen einzelnen Record.
Für die meisten Automatisierungen reicht der Upsert. Die ID-basierten Routen brauchst du, wenn du mehrere gleichnamige Records desselben Typs getrennt verwalten musst.
Die ganze Zone exportieren
Für Backups, Versionierung oder eine Migration exportierst du die komplette Zone als BIND-Zonefile.
curl --request GET \
--url https://api.pph.systems/api/domains/deine-domain.de/records/export \
--header 'Accept: text/plain' \
--header 'Authorization: Bearer sk_live_XXXX'
Du erhältst ein Standard-Zonefile. Jeder Eintrag ist mit seiner Record-ID als Kommentar versehen.
$ORIGIN deine-domain.de.
$TTL 300
; #101
www IN A 192.0.2.1
; #102
@ IN MX 10 mail.deine-domain.de.
; #103
@ IN TXT "v=spf1 mx -all"
Ohne den Header Accept: text/plain bekommst du dieselbe Zone als JSON zurück.
Eine ganze Zone importieren
Mit dem Import spielst du eine komplette Zone aus einem Zonefile ein. Achtung: Der Import ist ein vollständiger Ersatz. Records, die nicht im Zonefile stehen, werden entfernt.
Deshalb läuft der Import standardmäßig als Testlauf (dry). Dabei wird nichts geändert, sondern nur geprüft, was passieren würde.
curl --request POST \
--url https://api.pph.systems/api/domains/deine-domain.de/records/import \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sk_live_XXXX' \
--header 'Content-Type: application/json' \
--data '{
"dry": true,
"zonefile": "$ORIGIN deine-domain.de.\n$TTL 300\n@ IN A 192.0.2.1\nwww IN A 192.0.2.1\n"
}'
Die Antwort zeigt dir die geparsten Records und bestätigt mit dry_run: true, dass noch nichts geändert wurde. Prüfe dieses Ergebnis. Erst wenn es passt, wiederholst du den Aufruf mit "dry": false, um die Zone tatsächlich zu ersetzen.
DNSSEC (in Entwicklung)
Über die Registry-Routen kannst du die DNSSEC-Konfiguration einer Domain abfragen und die DS-Records am Registrar setzen. Der aktuelle Zustand sieht so aus:
{
"dnssec": false,
"dnssecData": [],
"dnssec_available": false
}
dnssec_available zeigt, ob DNSSEC für die Domain nutzbar ist. Das setzt einen externen Nameserver-Setup voraus. Mit den Standard-Nameservern steht das Feld auf false.
Diese Routen sind noch nicht final dokumentiert und ihr Antwortformat kann sich ändern. Wenn du DNSSEC produktiv nutzen möchtest, sprich uns am besten kurz an.
Praxisbeispiel: ein DynDNS-Skript
Der Upsert eignet sich ideal für DynDNS. Das folgende Bash-Skript ermittelt deine öffentliche IPv4 und IPv6 und schreibt sie in einen A– und AAAA-Record. Da Upsert anlegt oder aktualisiert, läuft es beim ersten wie bei jedem weiteren Durchlauf gleich.
#!/bin/bash
set -euo pipefail
API_HOST="api.pph.systems"
API_TOKEN="sk_live_XXXX"
DOMAIN="deine-domain.de"
SUBDOMAIN="home"
updateRecord() {
local type="$1" content="$2"
local payload
payload=$(jq -n \
--arg name "$SUBDOMAIN" --arg type "$type" --arg content "$content" \
'')
curl -s --request PATCH \
--url "https://$/api/domains/$/record/upsert" \
--header 'Accept: application/json' \
--header "Authorization: Bearer $" \
--header 'Content-Type: application/json' \
--data "$payload"
}
IPV4=$(curl --max-time 3 -4 -sL https://pph.sh/ip.php || true)
IPV6=$(curl --max-time 3 -6 -sL https://pph.sh/ip.php || true)
if [ -z "$IPV4" ] && [ -z "$IPV6" ]; then
echo "Weder IPv4 noch IPv6 gefunden." >&2
exit 1
fi
[ -n "$IPV4" ] && updateRecord "A" "$IPV4"
[ -n "$IPV6" ] && updateRecord "AAAA" "$IPV6"
Leg das Skript in einen Cronjob, und deine Subdomain zeigt immer auf deine aktuelle Anschluss-IP. Nutze dafür einen Token mit Schreibrechten, den du am besten per Gated Route nur auf die Upsert-Route und diese eine Domain einschränkst.
Wie geht es weiter?
- Wie du deinen Token passend absicherst, steht in Wie ist die API abgesichert?.
- Fehlermeldungen erklärt API-Antworten und Fehler verstehen.
Noch Fragen?
Technische Fragen zur API beantworten dir unsere Entwickler direkt in unserem Discord. Stell deine Frage im Entwickler-Channel und pinge das Dev-Team an.