Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Linux 13.06.2026 · 10 min Lesezeit

netcup SCP REST API einrichten und nutzen: Server automatisieren ohne SOAP

Die SOAP-Schnittstelle des netcup SCP ist seit Mai 2026 abgeschaltet. Mit der neuen REST API auf Basis von OAuth2 und OpenAPI 3.0 automatisierst du Server-Lifecycle, Snapshots und Failover-IPs bequem per curl oder Python-Skript.

Moderne Server-Infrastruktur mit leuchtenden Toggle-Schaltern symbolisiert Feature-Flag-Verwaltung

Der netcup Server Control Panel (SCP) hat eine neue REST API, die den veralteten SOAP-Webservice vollständig ersetzt. Wer Server, Snapshots oder Failover-IPs bislang per SOAP-Skripten steuerte, muss spätestens seit dem 1. Mai 2026 migriert haben – die SOAP-Schnittstelle ist seitdem abgeschaltet. Die neue REST API basiert auf OpenAPI 3.0, nutzt OAuth2 über Keycloak und liefert alle Antworten als JSON. Diese Anleitung zeigt dir, wie du dich einmalig authentifizierst, einen Refresh-Token sicher speicherst und damit vollständige Server-Automatisierung per curl oder Python-Skript umsetzt – ohne Browser-Login bei jedem Aufruf.

Voraussetzungen

  • Aktiver netcup-Account mit mindestens einem vServer oder Root-Server
  • Zugang zum Server Control Panel unter www.servercontrolpanel.de mit gültigem SCP-Passwort
  • Linux- oder macOS-System mit curl (vorinstalliert) und jq (apt install jq / brew install jq)
  • Für Python-Skripte: Python 3.9+ 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

Bevor du loslégst, lohnt ein kurzer Blick auf die Unterschiede. Die neue REST API ist kein einfaches Wrapper-Update – das Authentifizierungsmodell ist grundlegend anders:

MerkmalREST API (neu)SOAP Webservice (alt)
StatusAktiv seit Okt. 2025Abgeschaltet 1. Mai 2026
ProtokollHTTP/REST + JSONSOAP/XML
AuthentifizierungOAuth2/Keycloak, Bearer-TokenKundennummer + API-Passwort direkt
SpezifikationOpenAPI 3.0 (Swagger-UI im SCP)WSDL
Basis-URLservercontrolpanel.de/scp-core/api/v1servercontrolpanel.de/api/...
Token-LebensdauerAccess: 300 s, Refresh: 30 TageSession-basiert
Toolingnetcup-cli, oapi-codegen-ClientsAltschnittstellen

Wer SOAP-Skripte noch betreibt, hat seit dem 1. Mai 2026 keine funktionierende API mehr. Die Migration ist Pflicht.

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 solltest du einmalig interaktiv via netcup-cli authentifizieren und nur den Refresh-Token persistent speichern.

Für den schnellen Einstieg per curl: Ersetze <KUNDENNUMMER> durch deine netcup-Kundennummer (das ist der Keycloak-Username) und <SCP-PASSWORT> durch dein 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 kopierst du in die nächste Zeile:

# Refresh-Token sicher speichern
echo '<REFRESH_TOKEN>' > ~/.netcup_refresh_token
chmod 600 ~/.netcup_refresh_token

Wichtiger Hinweis: Die Kundennummer ist der Keycloak-Username beim Login. Die interne user_id (Keycloak-ID) ist eine separate, unveränderliche ID aus dem JWT-Token – 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. Du generierst ihn bei jedem Skriptlauf frisch 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}/ brauchst du deine interne Keycloak-ID. Diese steckt als Feld id im JWT-Payload:

# user_id aus dem JWT-Payload extrahieren
echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq '.id'

Speichere diesen Wert als Variable für spätere Requests: USER_ID="<Ausgabe-von-oben>".

Verifizieren: Der Befehl gibt eine UUID-artige Zeichenkette aus (z. B. "a1b2c3d4-..."). Das ist deine user_id – nicht deine Kundennummer.

Schritt 4: Eigene Server abfragen

Mit dem Access-Token in der Variable $TOKEN rufst du alle deine 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 (IDs beginnen mit "v")
SERVER_ID="vXXXXXXXX"
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://www.servercontrolpanel.de/scp-core/api/v1/servers/$SERVER_ID" | jq .

Verifizieren: Die Ausgabe enthält ein JSON-Array deiner Server mit Feldern wie id, hostname, state ("running" oder "off") und der IP-Adresse.

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: "running")
curl -s -X PATCH \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{"state": "running"}' \
  "https://www.servercontrolpanel.de/scp-core/api/v1/servers/$SERVER_ID"

Die API ist vollständig case-sensitive. "Running" oder "OFF" führen zu Fehlern – ausschließlich Kleinbuchstaben verwenden.

Verifizieren: Die API gibt die aktualisierte Server-Ressource zurück; das Feld state zeigt den neuen Zustand. Einige Operationen erzeugen asynchrone Tasks (dazu mehr in Schritt 6).

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) entnimmst du 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.

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: "running" | "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))

Speichere dieses Skript als netcup_api.py und starte es mit python3 netcup_api.py. Für Cronjobs legst du die Refresh-Token-Datei ebenfalls unter ~root/.netcup_refresh_token mit chmod 600 ab.

Schritt 8: netcup-cli als komfortables Werkzeug

Das Python-CLI-Tool netcup-cli kapselt die gesamte OAuth2-Logik inklusive Device-Code-Flow (Browser öffnet sich einmalig für sicheren Login ohne Passwort im Klartext) und persistiert Credentials in ~/.config/netcup-cli/credentials (JSON, chmod 600):

# Installation
pip install git+https://github.com/pavelpikta/netcup-cli.git

# 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>
netcup servers snapshots delete <SERVER_ID> <SNAPSHOT_ID>

# rDNS und Tasks
netcup rdns list
netcup tasks list

netcup-cli wartet bei asynchronen Operationen wie dem Snapshot-Erstellen automatisch auf den Abschluss – kein manuelles Pollen von /api/v1/tasks/{id} nötig.

Wichtige Endpunkte im Überblick

EndpunktMethodeBeschreibung
/serversGETAlle eigenen Server auflisten
/servers/{id}GETEinzelnen Server abrufen
/servers/{id}PATCHState/Hostname ändern (merge-patch+json)
/users/{userId}/failoverips/v4GETFailover-IPv4-Liste
/users/{userId}/failoverips/v4/{ipId}PATCHFailover-IP zuweisen
/users/{userId}/failoverips/v6GETFailover-IPv6-Liste
/api/v1/openapiGETOpenAPI-Spec abrufen (Auth erforderlich)
/tasks/{id}GETAsync-Task-Status abfragen

Die vollständige Swagger-UI ist direkt im SCP unter „REST API Docs" (oben rechts) erreichbar – inklusive „Try it out"-Funktion für alle Endpunkte.

Troubleshooting / Typische Fehler

HTTP 415 beim PATCH

Du verwendest Content-Type: application/json statt application/merge-patch+json. Beim PATCH auf /servers/{id} ist ausschließlich application/merge-patch+json zulässig. Korrigiere den Header und wiederhole den Request.

Mehrere Attribute gleichzeitig patchen schlägt fehl

Pro PATCH-Request ist nur ein Attribut erlaubt. Willst du state und nickname gleichzeitig setzen, sendest du zwei separate Requests. Mehrere Felder in einem Body werden ignoriert oder führen zu Fehlern.

HTTP 401 – Token abgelaufen

Der Access-Token ist nur 300 Sekunden gültig. Fange 401-Antworten ab und generiere automatisch einen neuen Access-Token aus dem Refresh-Token. Wenn auch der Refresh-Token abgelaufen ist (30 Tage ohne Nutzung), musst du dich erneut einmalig authentifizieren.

Kundennummer vs. user_id verwechselt

Die Kundennummer ist der Keycloak-Username für den Login. Endpunkte unter /users/{userId}/ erwarten die interne Keycloak-ID aus dem JWT-Token. Den Extraktionsbefehl findest du in Schritt 3.

Case-Sensitivity-Fehler

"Running", "OFF", "ServerID" – die API akzeptiert ausschließlich Kleinbuchstaben. Überprüfe alle Werte in deinen Requests auf Großbuchstaben.

Failover-IP lässt sich nicht zuweisen

Prüfe 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. Immer restriktive Dateiberechtigungen setzen: 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?

Nur 300 Sekunden (5 Minuten). Für länger laufende Skripte muss der Access-Token regelmäßig per Refresh-Token erneuert werden. Am einfachsten: bei HTTP 401 automatisch einen neuen Token anfordern.

Kann ich die REST API vollständig ohne Browser nutzen?

Ja – nach einmaliger interaktiver Authentifizierung (Device-Code-Flow per netcup auth login oder Password-Grant per curl) speicherst du den Refresh-Token in einer Datei (chmod 600) und generierst bei jedem Skriptlauf daraus einen neuen Access-Token. Kein Browser-Login mehr nötig.

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 gibt sofort eine Task-ID zurück. Den Fortschritt kannst du per GET /api/v1/tasks/{id} pollen. netcup-cli erledigt das automatisch im Hintergrund.

Wie sichere ich den API-Zugang zusätzlich ab?

Im SCP unter „REST API Settings" kannst du IP-Adressen und CIDR-Ranges als Whitelist eintragen, sodass der Token von unbekannten IPs nicht genutzt werden kann. Für Produktionsumgebungen ist das dringend empfohlen.

Fazit

Die Migration von SOAP auf die neue SCP REST API ist technisch unkompliziert – das größte Hindernis ist das andere Authentifizierungsmodell. Sobald der Refresh-Token einmalig sicher gespeichert ist, ist die vollständige Server-Automatisierung per curl oder Python-Skript genauso einfach wie zuvor. Die gut dokumentierte OpenAPI 3.0-Spec (direkt im SCP als Swagger-UI) macht es leicht, neue Endpunkte zu erkunden. Wer mehr als ein paar Ad-hoc-Befehle plant, greift am besten zum netcup-cli – es kapselt Token-Handling, Device-Code-Flow und asynchrones Task-Polling sauber weg. Für Monitoring-Setups lohnt ein Blick auf den netcupscp-exporter, der Server-Metriken als Prometheus-Endpunkt bereitstellt.

Weiterführende Anleitungen und Quellen