netcup SCP REST API einrichten und nutzen: Server automatisieren ohne SOAP
Die SOAP-Schnittstelle des netcup SCP ist seit Mai 2026 abgeschaltet. So nutzen Sie die REST API mit OAuth2: Token holen, Server per curl oder Python steuern, Failover-IPs umziehen und Tasks verfolgen.
Geprüft am 29.09.2026
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Mehr dazu

Das netcup Server Control Panel (SCP) hat eine REST API, die den SOAP-Webservice ersetzt. Die SOAP-Schnittstelle ist seit dem 1. Mai 2026 abgeschaltet; Skripte für Server, Snapshots oder Failover-IPs müssen auf REST umgestellt sein. Die REST API basiert auf OpenAPI 3.0, nutzt OAuth2 über Keycloak und antwortet in JSON. Diese Anleitung zeigt, wie Sie sich einmalig authentifizieren, einen Refresh-Token sicher speichern und Server per curl oder Python-Skript ohne Browser-Login steuern.
Voraussetzungen
- Aktiver netcup-Account mit mindestens einem vServer oder Root-Server
- Zugang zum Server Control Panel unter
www.servercontrolpanel.demit gültigem SCP-Passwort - Linux- oder macOS-System mit
curl(vorinstalliert) undjq(apt install jq/brew install jq) - Für Python-Skripte: Python 3.10+ und
pip install requests - Optional: IP-Whitelist für REST API Settings im SCP vorbereitet (empfohlen für Produktion)
Schritt 1: REST vs. SOAP – was sich wirklich ändert
Die REST API ist kein Wrapper-Update, das Authentifizierungsmodell ist grundlegend anders:
| Merkmal | REST API (neu) | SOAP Webservice (alt) |
|---|---|---|
| Status | Aktiv seit Okt. 2025 | Abgeschaltet 1. Mai 2026 |
| Protokoll | HTTP/REST + JSON | SOAP/XML |
| Authentifizierung | OAuth2/Keycloak, Bearer-Token | Kundennummer + API-Passwort direkt |
| Spezifikation | OpenAPI 3.0 (Swagger-UI im SCP) | WSDL |
| Basis-URL | servercontrolpanel.de/scp-core/api/v1 | servercontrolpanel.de/api/... |
| Token-Lebensdauer | Access: 300 s, Refresh: 30 Tage | Session-basiert |
| Tooling | netcup-scp-cli, oapi-codegen-Clients | Altschnittstellen |
SOAP-Skripte funktionieren seit dem 1. Mai 2026 nicht mehr.
Verifizieren: Suchen Sie in Ihren Skripten und Cronjobs nach WSDL, SoapClient oder servercontrolpanel.de/WSEndUser. Jede Fundstelle muss auf die REST API umgestellt werden.
Schritt 2: Einmalige Authentifizierung – Refresh-Token holen
Die SCP REST API nutzt OAuth2 mit Keycloak (Realm: scp, Client-ID: scp). Für vollständige Automatisierung ohne Browser gibt es zwei Wege: den Device-Code-Flow (empfohlen, kein Passwort wird gespeichert) über das CLI-Tool oder den Password-Grant per curl für schnelles Scripting. Letzterer verstößt gegen OAuth 2.0 Security BCP (RFC 9700) – für Produktionsumgebungen authentifizieren Sie sich einmalig interaktiv per Device-Code-Flow (z. B. mit netcup auth login, Schritt 8) und speichern nur den Refresh-Token.
Für den schnellen Einstieg per curl: Ersetzen Sie <KUNDENNUMMER> durch Ihre netcup-Kundennummer (das ist der Keycloak-Username) und <SCP-PASSWORT> durch Ihr SCP-Passwort:
# Einmalig: Refresh-Token per Password-Grant holen
curl -s -X POST \
'https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token' \
-d 'client_id=scp' \
-d 'grant_type=password' \
-d 'username=<KUNDENNUMMER>' \
-d 'password=<SCP-PASSWORT>' \
-d 'scope=offline_access openid' | jq .Die Antwort enthält access_token, refresh_token und weitere Felder. Den refresh_token-Wert kopieren Sie in die nächste Zeile:
# Refresh-Token sicher speichern
echo '<REFRESH_TOKEN>' > ~/.netcup_refresh_token
chmod 600 ~/.netcup_refresh_tokenWichtiger Hinweis: Die Kundennummer ist der Keycloak-Username beim Login. Die interne user_id ist eine separate numerische ID des SCP; sie wird für Endpunkte wie /users/{userId}/failoverips/ benötigt und ist nicht die Kundennummer.
Verifizieren: Der Befehl liefert ein JSON-Objekt mit dem Schlüssel refresh_token. Die Datei ~/.netcup_refresh_token existiert und hat Berechtigungen -rw------- (überprüfen mit ls -la ~/.netcup_refresh_token).
Schritt 3: Access-Token generieren und user_id extrahieren
Der Access-Token ist nur 300 Sekunden (5 Minuten) gültig. Sie erzeugen ihn bei jedem Skriptlauf neu aus dem langlebigen Refresh-Token:
# Access-Token aus Refresh-Token generieren und in Variable speichern
TOKEN=$(curl -s -X POST \
'https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token' \
-d 'client_id=scp' \
-d "refresh_token=$(cat ~/.netcup_refresh_token)" \
-d 'grant_type=refresh_token' | jq -r '.access_token')
echo "Token geladen: ${TOKEN:0:20}..."Für API-Endpunkte unter /users/{userId}/ brauchen Sie Ihre interne SCP-User-ID. Sie steht im Feld id der OpenID-Connect-Userinfo:
# user_id über den Userinfo-Endpunkt abfragen
USER_ID=$(curl -s -H "Authorization: Bearer $TOKEN" \
'https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/userinfo' | jq -r '.id')
echo "$USER_ID"Verifizieren: echo "Token geladen: ..." zeigt den Anfang eines Tokens (nicht null), und echo "$USER_ID" gibt eine Zahl aus. Das ist Ihre user_id, nicht Ihre Kundennummer.
Schritt 4: Eigene Server abfragen
Mit dem Access-Token in der Variable $TOKEN rufen Sie alle Ihre Server ab:
# Alle eigenen Server auflisten
curl -s -H "Authorization: Bearer $TOKEN" \
'https://www.servercontrolpanel.de/scp-core/api/v1/servers' | jq .Für einen einzelnen Server mit bekannter Server-ID:
# Einzelnen Server abrufen (numerische ID aus der Liste, Feld "id")
SERVER_ID="12345"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.servercontrolpanel.de/scp-core/api/v1/servers/$SERVER_ID" | jq .Verifizieren: Die Liste ist ein JSON-Array Ihrer Server mit Feldern wie id, name, hostname und nickname. Der Einzelabruf enthält zusätzlich die IP-Adressen und unter serverLiveInfo.state den Zustand (z. B. RUNNING oder SHUTOFF).
Schritt 5: Server ein- und ausschalten
PATCH-Requests auf /servers/{id} erfordern den Content-Type application/merge-patch+json – nicht das übliche application/json. Außerdem darf pro Request nur ein Attribut geändert werden. Beides sind häufige Fallstricke:
# Server ausschalten (state: "OFF")
curl -s -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/merge-patch+json" \
-d '{"state": "OFF"}' \
"https://www.servercontrolpanel.de/scp-core/api/v1/servers/$SERVER_ID"
# Server einschalten (state: "ON")
curl -s -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/merge-patch+json" \
-d '{"state": "ON"}' \
"https://www.servercontrolpanel.de/scp-core/api/v1/servers/$SERVER_ID"Die API ist case-sensitive: Pfade und Feldnamen schreiben Sie klein wie in der Dokumentation, die Werte für state laut OpenAPI-Spezifikation groß (ON, OFF). Für hartes Ausschalten hängen Sie ?stateOption=POWEROFF an, für einen Neustart bei ON ?stateOption=RESET oder POWERCYCLE.
Verifizieren: Die API antwortet mit HTTP 200 oder mit HTTP 202 und einem Task-Objekt (uuid, state). Den Fortschritt fragen Sie mit GET /api/v1/tasks/{uuid} ab; danach zeigt der Einzelabruf des Servers unter serverLiveInfo.state SHUTOFF bzw. RUNNING.
Schritt 6: Failover-IPs verwalten
Failover-IPs werden über den user_id-Pfad verwaltet. Zunächst alle vorhandenen IPv4-Adressen abrufen:
# Failover-IPv4-Liste abrufen
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.servercontrolpanel.de/scp-core/api/v1/users/$USER_ID/failoverips/v4" | jq .Nur IPs mit dem Flag "editable": true können per API einem anderen Server zugewiesen werden. Die IP-ID (IP_ID) entnehmen Sie der Antwort:
# Failover-IP einem Server zuweisen
IP_ID="<IP_ID_AUS_VORHERIGER_ABFRAGE>"
curl -s -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/merge-patch+json" \
-d "{\"serverId\": $SERVER_ID}" \
"https://www.servercontrolpanel.de/scp-core/api/v1/users/$USER_ID/failoverips/v4/$IP_ID"Wichtig: Zwischen zwei Zuweisungen derselben IP auf unterschiedliche Server gilt ein Rate-Limit von 301 Sekunden. Wer automatisiertes Failover implementiert, muss diese Pause einplanen. Bei IPv6 heißt das entsprechende Feld networkPrefix statt ip. Das Routing ist nur auf Server am selben Standort wie die Failover-IP möglich (sonst HTTP 400).
Verifizieren: Die Zuweisung antwortet mit HTTP 202 und einem Task. Nach Abschluss zeigt die erneute GET-Abfrage der Failover-IPs bei der IP unter server den neuen Server.
Schritt 7: Python-Skript für robuste Automatisierung
Für längerlaufende Automatisierungen empfiehlt sich Python mit automatischer Token-Erneuerung bei HTTP 401. Das folgende Skript legt eine saubere Grundlage:
import requests
import json
KEYCLOAK_URL = "https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token"
API_BASE = "https://www.servercontrolpanel.de/scp-core/api/v1"
def get_access_token(refresh_token: str) -> str:
resp = requests.post(KEYCLOAK_URL, data={
"client_id": "scp",
"grant_type": "refresh_token",
"refresh_token": refresh_token,
})
resp.raise_for_status()
return resp.json()["access_token"]
def list_servers(token: str) -> list:
headers = {"Authorization": f"Bearer {token}"}
resp = requests.get(f"{API_BASE}/servers", headers=headers)
resp.raise_for_status()
return resp.json()
def set_server_state(token: str, server_id: str, state: str) -> dict:
# state: "ON" | "OFF"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/merge-patch+json",
}
resp = requests.patch(
f"{API_BASE}/servers/{server_id}",
headers=headers,
json={"state": state}
)
resp.raise_for_status()
return resp.json()
# Nutzung
with open("/root/.netcup_refresh_token") as f:
refresh = f.read().strip()
token = get_access_token(refresh)
servers = list_servers(token)
print(json.dumps(servers, indent=2))Speichern Sie das Skript als netcup_api.py und starten Sie es mit python3 netcup_api.py. Das Skript liest den Refresh-Token aus /root/.netcup_refresh_token; passen Sie den Pfad an, wenn der Cronjob unter einem anderen Benutzer läuft, und setzen Sie chmod 600.
Verifizieren: Das Skript gibt die Serverliste als JSON aus. Ein HTTPError: 400 beim Token-Abruf bedeutet einen abgelaufenen oder falsch kopierten Refresh-Token.
Schritt 8: netcup-cli als komfortables Werkzeug
Das Community-Tool netcup-scp-cli (Befehl netcup, nicht von netcup selbst) kapselt die OAuth2-Logik inklusive Device-Code-Flow (einmaliger Login im Browser, kein Passwort im Skript) und speichert den Refresh-Token in ~/.config/netcup-scp-cli/credentials (JSON, chmod 600):
# Installation (Python 3.10+, am besten mit pipx)
pipx install netcup-scp-cli
# Einmalige Authentifizierung (öffnet Browser für Device-Code-Flow)
netcup auth login
# Server-Operationen
netcup servers list
netcup servers power <SERVER_ID> on
netcup servers power <SERVER_ID> off
# Snapshots
netcup servers snapshots create <SERVER_ID> --name vor-update
netcup servers snapshots delete <SERVER_ID> <SNAPSHOT_ID>
# rDNS und Tasks
netcup rdns ipv4 get <IPV4>
netcup tasks listAsynchrone Operationen wie Snapshots verfolgen Sie mit netcup tasks list bzw. netcup tasks get <UUID>.
Verifizieren: netcup auth show meldet eine vorhandene Credentials-Datei, netcup servers list gibt Ihre Server als JSON aus.
Wichtige Endpunkte im Überblick
| Endpunkt | Methode | Beschreibung |
|---|---|---|
| /servers | GET | Alle eigenen Server auflisten |
| /servers/{id} | GET | Einzelnen Server abrufen |
| /servers/{id} | PATCH | State/Hostname ändern (merge-patch+json) |
| /users/{userId}/failoverips/v4 | GET | Failover-IPv4-Liste |
| /users/{userId}/failoverips/v4/{ipId} | PATCH | Failover-IP zuweisen |
| /users/{userId}/failoverips/v6 | GET | Failover-IPv6-Liste |
| /api/v1/openapi | GET | OpenAPI-Spec abrufen (Auth erforderlich) |
| /tasks/{uuid} | GET | Async-Task-Status abfragen |
Die vollständige Dokumentation erreichen Sie im SCP über den Menüpunkt „API“ in der oberen Leiste unter „REST API Docs“.
Troubleshooting / Typische Fehler
HTTP 415 beim PATCH
Sie verwenden Content-Type: application/json statt application/merge-patch+json. Beim PATCH auf /servers/{id} ist ausschließlich application/merge-patch+json zulässig. Korrigieren Sie den Header und wiederholen Sie den Request.
Mehrere Attribute gleichzeitig patchen schlägt fehl
Pro PATCH-Request ist nur ein Attribut erlaubt. Wollen Sie state und nickname setzen, senden Sie zwei separate Requests.
HTTP 401 – Token abgelaufen
Der Access-Token ist nur 300 Sekunden gültig. Fangen Sie 401-Antworten ab und erzeugen Sie automatisch einen neuen Access-Token aus dem Refresh-Token. Ist auch der Refresh-Token abgelaufen (30 Tage ohne Nutzung), authentifizieren Sie sich erneut.
Kundennummer vs. user_id verwechselt
Die Kundennummer ist der Keycloak-Username für den Login. Endpunkte unter /users/{userId}/ erwarten die interne SCP-User-ID aus dem Userinfo-Endpunkt. Den Befehl finden Sie in Schritt 3.
Case-Sensitivity-Fehler
Pfade und Feldnamen sind case-sensitive: "ServerID" statt "serverId" schlägt fehl. Enum-Werte schreiben Sie so, wie die OpenAPI-Spezifikation sie vorgibt, z. B. "ON" und "OFF" für state.
Failover-IP lässt sich nicht zuweisen
Prüfen Sie per GET-Request, ob das Feld editable der IP true ist. Nur solche IPs können per API bewegt werden. Außerdem gilt das Rate-Limit von 301 Sekunden zwischen zwei Zuweisungen derselben IP.
Refresh-Token-Datei ohne korrekte Berechtigungen
Ohne chmod 600 können andere Systemnutzer den Token lesen. Setzen Sie restriktive Dateiberechtigungen: chmod 600 ~/.netcup_refresh_token.
Häufige Fragen
Brauche ich einen separaten CCP-API-Key für die SCP REST API?
Nein. Die SCP REST API verwendet OAuth2/Keycloak mit Kundennummer und SCP-Passwort. CCP-API-Keys (unter Stammdaten > API im CCP) sind für die separate CCP-API zur Domain-Verwaltung – nicht für die SCP REST API.
Wie lange ist ein Access-Token gültig?
300 Sekunden. Längere Skripte fordern bei HTTP 401 per Refresh-Token einen neuen an.
Kann ich die REST API vollständig ohne Browser nutzen?
Ja. Nach einmaliger Authentifizierung (Device-Code-Flow per netcup auth login oder Password-Grant per curl) speichern Sie den Refresh-Token in einer Datei (chmod 600) und erzeugen bei jedem Skriptlauf daraus einen neuen Access-Token.
Welche Operationen unterstützt die REST API?
Server-Lifecycle (ein-/ausschalten, Reset, Poweroff), Hostname und Nickname setzen, Snapshots erstellen/löschen/wiederherstellen/exportieren, Failover-IPv4 und -IPv6 zuweisen, rDNS verwalten, Rescue-System aktivieren, Firewall-Policies, SSH-Keys, VLANs, ISO-Images, Metriken und Logs.
Was passiert bei asynchronen Operationen?
Die API antwortet mit HTTP 202 und einem Task-Objekt mit uuid. Den Fortschritt fragen Sie per GET /api/v1/tasks/{uuid} ab, mit dem CLI per netcup tasks get <UUID>.
Wie sichere ich den API-Zugang zusätzlich ab?
Im SCP unter „REST API Settings“ können Sie IP-Adressen und CIDR-Ranges als Whitelist eintragen, sodass der Token von unbekannten IPs nicht genutzt werden kann. Für Produktivumgebungen ist das empfehlenswert.
Fazit
Die Umstellung von SOAP auf die SCP REST API scheitert meist am neuen Authentifizierungsmodell, selten an den Endpunkten. Ist der Refresh-Token sicher gespeichert, steuern Sie Server per curl oder Python wie zuvor. Die OpenAPI-Spezifikation im SCP zeigt alle Endpunkte und gültigen Werte. netcup-scp-cli kapselt Token-Handling und Device-Code-Flow; der netcupscp-exporter stellt Server-Metriken als Prometheus-Endpunkt bereit.
Weiterführende Anleitungen und Quellen
- netcup Failover-IP: Bestellung, SCP-Zuweisung und Server-zu-Server-Wechsel
- Das netcup Server Control Panel (SCP): Alle Funktionen im Überblick
- VPS absichern und härten: UFW, SSH-Keys und Fail2Ban (Hetzner/Netcup)
- netcup VPS-Snapshots: Offline- vs. Online-Snapshot, Export und Wiederherstellung
- netcup Helpcenter: SCP REST API (offiziell)
- netcup Community Forum: Howto REST API nutzen (Praxisbeispiele)
- GitHub: netcup-scp-cli (Python-CLI für die SCP REST API, Community-Projekt)


