81 lines
3.5 KiB
Markdown
81 lines
3.5 KiB
Markdown
# Netcup SCP REST API Access
|
|
|
|
## Authentication
|
|
|
|
The netcup SCP API at `servercontrolpanel.de` uses **Keycloak OIDC** — NOT API key headers. The CCP API key from `customercontrolpanel.de` Master Data does **not** work with the SCP REST API directly.
|
|
|
|
### Get a token
|
|
|
|
```bash
|
|
TOKEN=$(curl -s "https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token" \
|
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
|
-d "grant_type=password&client_id=scp&username=${NETCUP_CUSTOMER}&password=${NETCUP_PASSWORD}&scope=openid" \
|
|
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token')")
|
|
```
|
|
|
|
| Parameter | Value | Source |
|
|
|-----------|-------|--------|
|
|
| Token endpoint | `https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token` | From `keycloak.js` in SCP UI |
|
|
| Client ID | `scp` | From `keycloak.js` |
|
|
| Grant type | `password` | Resource owner password grant |
|
|
| Username | CCP customer number (numeric, e.g. `389212`) | From CCP Master Data |
|
|
| Password | CCP account password | User-provided |
|
|
| Scope | `openid` | Required for ID token |
|
|
| Token lifetime | 300 seconds (5 min) | From token response `expires_in` |
|
|
| Refresh | 1800 seconds (30 min) | From token response `refresh_expires_in` |
|
|
|
|
### API base URL
|
|
|
|
The SCP has three API paths:
|
|
|
|
| Path | Purpose | Status |
|
|
|------|---------|--------|
|
|
| `https://www.servercontrolpanel.de/scp-core/api/v1/` | Server management CRUD | ✅ Works (returns JSON) |
|
|
| `https://www.servercontrolpanel.de/scp-agent/api/v1/` | Agent/service operations | ⚠️ Returns 403 Forbidden |
|
|
| `https://www.servercontrolpanel.de/scp-ui/api/v1/` | UI data endpoints | ❌ Returns HTML login page, not JSON |
|
|
|
|
**Always use `scp-core` for server operations.**
|
|
|
|
## Available endpoints
|
|
|
|
### List servers
|
|
```bash
|
|
curl -s "https://www.servercontrolpanel.de/scp-core/api/v1/servers" \
|
|
-H "Authorization: Bearer ${TOKEN}"
|
|
```
|
|
Returns: `[{"id": 890903, "name": "v2202607377162478911", "template": {"name": "RS 2000 G12"}}]`
|
|
|
|
### Single server details
|
|
```bash
|
|
curl -s "https://www.servercontrolpanel.de/scp-core/api/v1/servers/890903" \
|
|
-H "Authorization: Bearer ${TOKEN}"
|
|
```
|
|
|
|
Returns: IP addresses, hostname, architecture, template name, disk available space, RAM.
|
|
|
|
### Templates / Images (provisioning)
|
|
```bash
|
|
curl -s "https://www.servercontrolpanel.de/scp-core/api/v1/templates" \
|
|
-H "Authorization: Bearer ${TOKEN}"
|
|
```
|
|
**Note:** May return `{"code": "error.notfound", "message": "Resource not found"}` for non-reseller accounts. This is a known limitation — provisioning via API may require reseller status with netcup.
|
|
|
|
## Credentials
|
|
|
|
Stored in `/root/.hermes/.env`:
|
|
```
|
|
NETCUP_CUSTOMER=389212
|
|
NETCUP_PASSWORD=<CCP password>
|
|
NETCUP_KEY=<API key from Master Data page>
|
|
NETCUP_API_KEY=<same as NETCUP_KEY>
|
|
```
|
|
|
|
The API key from the Master Data page is NOT used by the REST API. The password grant flows use the customer number + CCP password directly. The API key exists for legacy SOAP/JSON-RPC endpoints.
|
|
|
|
## Known limitations
|
|
|
|
- **Token expires every 5 minutes** — need to re-authenticate or implement refresh flow for long-running operations
|
|
- **Provisioning may be restricted** — `/templates` and `/images` return 404 for non-reseller accounts
|
|
- **This is the SCP (Server Control Panel), not CCP** — the CCP (`customercontrolpanel.de`) has a separate API surface for billing/invoicing
|
|
- **Discovered Jul 8 2026** — after multiple failed attempts with API key auth that returned 404/401, the working auth flow was found by inspecting `keycloak.js` in the SCP UI JavaScript bundle
|